Мемнотация
memnotationwiki
https://memnotation.miraheze.org/wiki/%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0
MediaWiki 1.42.1
first-letter
Медиа
Служебная
Обсуждение
Участник
Обсуждение участника
Мемнотация вики
Мемнотация вики talk
Файл
Обсуждение файла
MediaWiki
Обсуждение MediaWiki
Шаблон
Обсуждение шаблона
Справка
Обсуждение справки
Категория
Обсуждение категории
Модуль
Обсуждение модуля
Шаблон:!-
10
266
693
2008-06-07T11:54:44Z
ruwiki>Alex Spade
0
-- удаляемый шаблон, ивики и категорию в документацию
wikitext
text/x-wiki
|-<noinclude>
{{doc}}
<!-- Пожалуйста, добавляйте категории и интервики на страницу документации! --></noinclude>
4f45a1a9fb060eda6d4afb6850044503035d52bd
Шаблон:Хх
10
260
681
2008-06-07T15:42:39Z
ruwiki>Alex Spade
0
wikitext
text/x-wiki
[[<noinclude>
{{doc}}
<!-- Пожалуйста, добавляйте категории и интервики на страницу документации! --></noinclude>
c18d284eaccac8b03717d7977a4bd795d3ad7f3c
Шаблон:Categorytree
10
305
771
2011-02-01T03:15:33Z
ruwiki>Artem Korzhimanov
0
[[ВП:←|←]] [[ВП:Перенаправления|Перенаправление]] на «[[Шаблон:Дерево категорий]]»
wikitext
text/x-wiki
#REDIRECT [[Шаблон:Дерево категорий]]
dbb44c74e7e2d0a61716eb7c903a7ecef6d38d15
Шаблон:Str len
10
166
374
2013-03-14T14:34:59Z
ruwiki>DR
0
wikitext
text/x-wiki
{{{{{|safesubst:}}}#invoke:String|len|s={{{1|}}}}}<noinclude>
{{doc}}
<!-- Add categories and interwikis to the /doc subpage, not here! -->
</noinclude>
95f10258d5214440d2706952656564f216c2e4cc
Шаблон:Str rep
10
136
314
2015-02-28T09:38:11Z
ruwiki>Rubinbot II
0
Защищена Шаблон:Str rep: Top used templates to be protected ([Редактирование=только администраторы] (бессрочно) [Переименование=только администраторы] (бессро
wikitext
text/x-wiki
<includeonly>{{{{{|safesubst:}}}#invoke:String|replace|source={{{1}}}|{{{2}}}|{{{3}}}|{{{4|1}}}}}</includeonly><noinclude>{{doc}}</noinclude>
c75032f150c372324c69a6f62ff4ab1492ad4cfa
Шаблон:Lang-fi
10
181
404
2015-06-22T08:43:43Z
ruwiki>DimaABot
0
Бот: удаление категории по запросу на [[ВП:РДБ]]
wikitext
text/x-wiki
[[финский язык|фин.]] {{langi|fi|{{{1}}}}}<noinclude>{{doc|Lang/doc}}
</noinclude>
16ac91b8e1e294e7687d57c0757c178f9662581c
Модуль:Namespace detect/data
828
76
124
2015-06-27T21:11:34Z
ruwiki>Draa kul
0
Защищена Модуль:Namespace detect/data: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только администрато…
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Namespace detect data --
-- This module holds data for [[Module:Namespace detect]] to be loaded per --
-- page, rather than per #invoke, for performance reasons. --
--------------------------------------------------------------------------------
local cfg = require('Module:Namespace detect/config')
local function addKey(t, key, defaultKey)
if key ~= defaultKey then
t[#t + 1] = key
end
end
-- Get a table of parameters to query for each default parameter name.
-- This allows wikis to customise parameter names in the cfg table while
-- ensuring that default parameter names will always work. The cfg table
-- values can be added as a string, or as an array of strings.
local defaultKeys = {
'main',
'talk',
'other',
'subjectns',
'demospace',
'demopage'
}
local argKeys = {}
for i, defaultKey in ipairs(defaultKeys) do
argKeys[defaultKey] = {defaultKey}
end
for defaultKey, t in pairs(argKeys) do
local cfgValue = cfg[defaultKey]
local cfgValueType = type(cfgValue)
if cfgValueType == 'string' then
addKey(t, cfgValue, defaultKey)
elseif cfgValueType == 'table' then
for i, key in ipairs(cfgValue) do
addKey(t, key, defaultKey)
end
end
cfg[defaultKey] = nil -- Free the cfg value as we don't need it any more.
end
local function getParamMappings()
--[[
-- Returns a table of how parameter names map to namespace names. The keys
-- are the actual namespace names, in lower case, and the values are the
-- possible parameter names for that namespace, also in lower case. The
-- table entries are structured like this:
-- {
-- [''] = {'main'},
-- ['wikipedia'] = {'wikipedia', 'project', 'wp'},
-- ...
-- }
--]]
local mappings = {}
local mainNsName = mw.site.subjectNamespaces[0].name
mainNsName = mw.ustring.lower(mainNsName)
mappings[mainNsName] = mw.clone(argKeys.main)
mappings['talk'] = mw.clone(argKeys.talk)
for nsid, ns in pairs(mw.site.subjectNamespaces) do
if nsid ~= 0 then -- Exclude main namespace.
local nsname = mw.ustring.lower(ns.name)
local canonicalName = mw.ustring.lower(ns.canonicalName)
mappings[nsname] = {nsname}
if canonicalName ~= nsname then
table.insert(mappings[nsname], canonicalName)
end
for _, alias in ipairs(ns.aliases) do
table.insert(mappings[nsname], mw.ustring.lower(alias))
end
end
end
return mappings
end
return {
argKeys = argKeys,
cfg = cfg,
mappings = getParamMappings()
}
d224f42a258bc308ef3ad8cc8686cd7a4f47d005
Модуль:Namespace detect/config
828
77
126
2015-06-27T21:11:46Z
ruwiki>Draa kul
0
Защищена Модуль:Namespace detect/config: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только администрат…
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Namespace detect configuration data --
-- --
-- This module stores configuration data for Module:Namespace detect. Here --
-- you can localise the module to your wiki's language. --
-- --
-- To activate a configuration item, you need to uncomment it. This means --
-- that you need to remove the text "-- " at the start of the line. --
--------------------------------------------------------------------------------
local cfg = {} -- Don't edit this line.
--------------------------------------------------------------------------------
-- Parameter names --
-- These configuration items specify custom parameter names. Values added --
-- here will work in addition to the default English parameter names. --
-- To add one extra name, you can use this format: --
-- --
-- cfg.foo = 'parameter name' --
-- --
-- To add multiple names, you can use this format: --
-- --
-- cfg.foo = {'parameter name 1', 'parameter name 2', 'parameter name 3'} --
--------------------------------------------------------------------------------
---- This parameter displays content for the main namespace:
-- cfg.main = 'main'
---- This parameter displays in talk namespaces:
-- cfg.talk = 'talk'
---- This parameter displays content for "other" namespaces (namespaces for which
---- parameters have not been specified):
-- cfg.other = 'other'
---- This parameter makes talk pages behave as though they are the corresponding
---- subject namespace. Note that this parameter is used with [[Module:Yesno]].
---- Edit that module to change the default values of "yes", "no", etc.
-- cfg.subjectns = 'subjectns'
---- This parameter sets a demonstration namespace:
-- cfg.demospace = 'demospace'
---- This parameter sets a specific page to compare:
cfg.demopage = 'page'
--------------------------------------------------------------------------------
-- Table configuration --
-- These configuration items allow customisation of the "table" function, --
-- used to generate a table of possible parameters in the module --
-- documentation. --
--------------------------------------------------------------------------------
---- The header for the namespace column in the wikitable containing the list of
---- possible subject-space parameters.
-- cfg.wikitableNamespaceHeader = 'Namespace'
---- The header for the wikitable containing the list of possible subject-space
---- parameters.
-- cfg.wikitableAliasesHeader = 'Aliases'
--------------------------------------------------------------------------------
-- End of configuration data --
--------------------------------------------------------------------------------
return cfg -- Don't edit this line.
0e4ff08d13c4b664d66b32c232deb129b77c1a56
Модуль:Color contrast/colors
828
152
346
2016-06-19T09:05:16Z
ruwiki>Dima st bk
0
Защищена Модуль:Color contrast/colors: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только администрато…
Scribunto
text/plain
return {
aliceblue = 0.92880068253475,
antiquewhite = 0.84646951707754,
aqua = 0.7874,
aquamarine = 0.8078549208338,
azure = 0.97265264954166,
beige = 0.8988459998705,
bisque = 0.80732327372979,
black = 0,
blanchedalmond = 0.85084439608156,
blue = 0.0722,
blueviolet = 0.12622014321946,
brown = 0.098224287876511,
burlywood = 0.51559844533893,
cadetblue = 0.29424681085422,
chartreuse = 0.76032025902623,
chocolate = 0.23898526114557,
coral = 0.37017930872924,
cornflowerblue = 0.30318641994179,
cornsilk = 0.93562110372965,
crimson = 0.16042199953026,
cyan = 0.7874,
darkblue = 0.018640801980939,
darkcyan = 0.20329317839046,
darkgoldenrod = 0.27264703559993,
darkgray = 0.39675523072563,
darkgreen = 0.091143429047575,
darkgrey = 0.39675523072563,
darkkhaki = 0.45747326349994,
darkmagenta = 0.07353047651207,
darkolivegreen = 0.12651920884889,
darkorange = 0.40016167026524,
darkorchid = 0.13413142174857,
darkred = 0.054889674531132,
darksalmon = 0.40541471563381,
darkseagreen = 0.43789249325969,
darkslateblue = 0.065792846227988,
darkslategray = 0.067608151928044,
darkslategrey = 0.067608151928044,
darkturquoise = 0.4874606277449,
darkviolet = 0.10999048339343,
deeppink = 0.23866895828276,
deepskyblue = 0.44481603395575,
dimgray = 0.14126329114027,
dimgrey = 0.14126329114027,
dodgerblue = 0.27442536991456,
firebrick = 0.10724525535015,
floralwhite = 0.95922484825004,
forestgreen = 0.18920812076002,
fuchsia = 0.2848,
gainsboro = 0.71569350050648,
ghostwhite = 0.94311261886323,
gold = 0.69860877428159,
goldenrod = 0.41919977809569,
gray = 0.2158605001139,
green = 0.15438342968146,
greenyellow = 0.80609472611453,
grey = 0.2158605001139,
honeydew = 0.96336535554782,
hotpink = 0.34658438169715,
indianred = 0.21406134963884,
indigo = 0.03107561486337,
ivory = 0.99071270600615,
khaki = 0.77012343394121,
lavender = 0.80318750514521,
lavenderblush = 0.90172748631046,
lawngreen = 0.73905893124963,
lemonchiffon = 0.94038992245622,
lightblue = 0.63709141280807,
lightcoral = 0.35522120733135,
lightcyan = 0.94587293494829,
lightgoldenrodyellow = 0.93348351018297,
lightgray = 0.65140563741982,
lightgreen = 0.69091979956865,
lightgrey = 0.65140563741982,
lightpink = 0.58566152734898,
lightsalmon = 0.4780675225206,
lightseagreen = 0.35050145117042,
lightskyblue = 0.56195637618331,
lightslategray = 0.23830165007287,
lightslategrey = 0.23830165007287,
lightsteelblue = 0.53983888284666,
lightyellow = 0.98161818392882,
lime = 0.7152,
limegreen = 0.44571042246098,
linen = 0.88357340984379,
magenta = 0.2848,
maroon = 0.045891942324215,
mediumaquamarine = 0.49389703310801,
mediumblue = 0.044077780212328,
mediumorchid = 0.21639251153773,
mediumpurple = 0.22905858091648,
mediumseagreen = 0.34393112338131,
mediumslateblue = 0.20284629471622,
mediumspringgreen = 0.70704308194184,
mediumturquoise = 0.5133827926448,
mediumvioletred = 0.14371899849357,
midnightblue = 0.02071786635086,
mintcream = 0.97834604947588,
mistyrose = 0.82183047859185,
moccasin = 0.80083000991567,
navajowhite = 0.76519682342785,
navy = 0.015585128108224,
oldlace = 0.91900633405549,
olive = 0.20027537200568,
olivedrab = 0.22593150951929,
orange = 0.4817026703631,
orangered = 0.25516243753416,
orchid = 0.31348806761439,
palegoldenrod = 0.78792647887614,
palegreen = 0.77936759006353,
paleturquoise = 0.76436077921714,
palevioletred = 0.28754994117889,
papayawhip = 0.87797100199835,
peachpuff = 0.74905589878251,
peru = 0.30113074877936,
pink = 0.63271070702466,
plum = 0.45734221587969,
powderblue = 0.68254586500605,
purple = 0.061477070432439,
rebeccapurple = 0.07492341159447,
red = 0.2126,
rosybrown = 0.32319457649407,
royalblue = 0.16663210743188,
saddlebrown = 0.097922285020521,
salmon = 0.36977241527596,
sandybrown = 0.46628543696283,
seagreen = 0.19734199706275,
seashell = 0.92737862206922,
sienna = 0.13697631337098,
silver = 0.52711512570581,
skyblue = 0.55291668518184,
slateblue = 0.14784278062136,
slategray = 0.20896704076536,
slategrey = 0.20896704076536,
snow = 0.96533341834849,
springgreen = 0.73052306068529,
steelblue = 0.20562642207625,
tan = 0.48237604163921,
teal = 0.16996855778968,
thistle = 0.56818401093733,
tomato = 0.30638612719415,
turquoise = 0.5895536427578,
violet = 0.40315452986676,
wheat = 0.74909702820482,
white = 1,
whitesmoke = 0.91309865179342,
yellow = 0.9278,
yellowgreen = 0.50762957208707,
}
6ae47fdb24de4eed5ec26d203faf5341a388987b
Шаблон:Wikidata/p570
10
271
703
2016-07-12T17:40:22Z
ruwiki>Putnik
0
скрытие значения из Викиданных при помощи «-»
wikitext
text/x-wiki
{{#switch:{{{1|}}}|-=|={{#invoke:Wikidata|formatStatements|property=p570|claim-module=Wikidata/date|claim-function=formatDateOfDeathClaim|nocat={{{nocat|}}}{{NAMESPACE}}}}|{{#invoke:Infocards|dateOfDeath|{{{2|}}}|{{{1|}}}|nocat={{{nocat|}}}{{NAMESPACE}}}}}}<noinclude>{{doc}}</noinclude>
a51af6d007d156cfeacb13a0a4a7471da7d4ed22
Шаблон:Население государства
10
180
402
2016-08-16T20:27:21Z
ruwiki>SandBot
0
/* top */удаление устаревшего ключа сортировки
wikitext
text/x-wiki
<includeonly>{{#switch: {{{1}}}
| Республика Южная Осетия = Население Южной Осетии{{!}}Население
| Население
}}</includeonly><noinclude>
{{doc}}
[[Категория:Шаблоны по странам]]
</noinclude>
e0568280ef5056e94f5f1abf1934f4188a52c35f
Шаблон:Str find
10
214
476
2016-11-07T15:00:14Z
ruwiki>Jack who built the house
0
последуем написанному в комментарии и перенесём категории на подстраницу
wikitext
text/x-wiki
{{ {{{|safesubst:}}}#invoke:String|str_find|source={{{1|}}}|{{{2|}}}}}<noinclude>
{{doc}}
<!-- Add categories and interwikis to the /doc subpage, not here! -->
</noinclude>
18d1469d30d27a82ee15fd2fb1ca12a34b5f5e87
Шаблон:Nobr
10
147
336
2016-12-02T13:15:38Z
ruwiki>Jack who built the house
0
используем класс nowrap
wikitext
text/x-wiki
<includeonly><span class="nowrap">{{{1}}}</span></includeonly><noinclude>
{{doc}}
<!-- Пожалуйста, добавляйте категории и интервики на страницу документации! -->
</noinclude>
989c6f164ed3a8543e916c8f1746ba1ab94fb068
Шаблон:Ambox
10
193
432
2017-02-15T11:02:18Z
ruwiki>Iniquity
0
теперь есть в модуле
wikitext
text/x-wiki
{{#invoke:Message box|ambox}}{{#ifeq:{{{small}}}|left|[[Категория:Страницы, использующие малые шаблоны-сообщения]]}}<noinclude>
{{doc}}
<!-- Categories go on the /doc subpage, and interwikis go on Wikidata. -->
</noinclude>
5345bd7c0e2430e3672a54d920abd0f0bf61dc61
Шаблон:Без уточнения
10
132
306
2017-03-12T19:54:44Z
ruwiki>Jack who built the house
0
бoлee кoppeктный пaттepн; нaпpимep, в «Haзвaниe (нeyтoчнeниe) (yтoчнeниe)» yтoчнeниeм дoлжнa cчитaтьcя тoлькo пocлeдняя чacть. вoзмoжнocть иcпол. бeз 1-гo пap. и пoдcтaн.
wikitext
text/x-wiki
<includeonly>{{ {{{|safesubst:}}}#invoke:String|replace|{{{1|{{ {{{|safesubst:}}}PAGENAME}}}}}|^%s*(.+)%s+%b()%s*$|%1||false}}</includeonly><noinclude>{{doc}}</noinclude>
1fcb3edb0be49656ae0f913e9a8fb4853264b480
Шаблон:Clear
10
188
420
2017-05-07T18:43:17Z
ruwiki>Stjn
0
Saint Johann переименовал страницу [[Шаблон:-]] в [[Шаблон:Clear]]: более понятное (хоть и менее используемое) название
wikitext
text/x-wiki
<div style="clear:{{{1|both}}};"></div><noinclude>{{doc}}</noinclude>
15e943687be5d8f8e27fa6cc7813bbfa85df72a9
Шаблон:-
10
189
422
2017-05-07T18:43:17Z
ruwiki>Stjn
0
Saint Johann переименовал страницу [[Шаблон:-]] в [[Шаблон:Clear]]: более понятное (хоть и менее используемое) название
wikitext
text/x-wiki
#перенаправление [[Шаблон:Clear]]
f3ec5262c8fab1ae984101008632fb9c091fb431
Шаблон:Вложенные кавычки
10
292
745
2017-05-14T16:34:35Z
ruwiki>Draa kul
0
Защитил «[[Шаблон:Вложенные кавычки]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только адм…
wikitext
text/x-wiki
{{replace
| {{#invoke:string|replace<!--
-->| {{#invoke:string|replace<!--
-->| {{#invoke:string|replace<!--
-->| {{#invoke:string|replace<!--
-->| {{{1|}}}
| pattern = %[%[(.?[^%]{{!}}]-)«(.[^«»]-)»(.?[^%]{{!}}]-){{!}}
| replace = {{хх}}%1<<%2>>%3{{!}}
| plain = false<!--
-->}}
| pattern = %[%[(.?[^%]{{!}}]-)«(.[^«»]-)»(.?[^%[{{!}}]-)%]%]
| replace = [[%1<<%2>>%3{{!}}%1«%2»%3]]
| plain = false<!--
-->}}
| pattern = «(.[^«»]-)»
| replace = „%1“
| plain = false<!--
-->}}
| pattern = <<(.[^<>]-)>>
| replace = «%1»
| plain = false<!--
-->}}}}<noinclude>{{doc}}</noinclude>
48611a5cc8c8ac357e4b2a083c1845c15462160e
Шаблон:Delink
10
263
687
2017-08-01T19:23:44Z
ruwiki>Q-bit array
0
Защитил «[[Шаблон:Delink]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только администраторы] (б…
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>#invoke:delink|delink}}<noinclude>
{{doc}}
</noinclude>
dbac86e53b946e60d5b6236381e8c31858e79ee5
Шаблон:Карточка/название
10
130
302
2017-08-01T19:26:37Z
ruwiki>Q-bit array
0
Защитил «[[Шаблон:Карточка/название]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только адм…
wikitext
text/x-wiki
{{#if:{{{1|}}}|{{{1}}}|{{без уточнения|{{PAGENAME}}}}}}<noinclude>
{{doc}}
</noinclude>
110edc6d8286f120a048863c68371720bd4e65ca
Шаблон:Карточка/имя
10
267
695
2017-08-01T19:26:40Z
ruwiki>Q-bit array
0
Защитил «[[Шаблон:Карточка/имя]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только админист…
wikitext
text/x-wiki
{{#if:{{{1|}}}|{{{1}}}|{{сначала имя|{{PAGENAME}}}}}}<noinclude>
{{doc}}
</noinclude>
c2c97d1196f5c50a2ec1aa866cd4004526a32383
Модуль:Category handler/config
828
70
112
2017-08-01T19:26:42Z
ruwiki>Q-bit array
0
Защитил «[[Модуль:Category handler/config]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только админист…
Scribunto
text/plain
--------------------------------------------------------------------------------
-- [[Module:Category handler]] configuration data --
-- Language-specific parameter names and values can be set here. --
-- For blacklist config, see [[Module:Category handler/blacklist]]. --
--------------------------------------------------------------------------------
local cfg = {} -- Don't edit this line.
--------------------------------------------------------------------------------
-- Start configuration data --
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Parameter names --
-- These configuration items specify custom parameter names. --
-- To add one extra name, you can use this format: --
-- --
-- foo = 'parameter name', --
-- --
-- To add multiple names, you can use this format: --
-- --
-- foo = {'parameter name 1', 'parameter name 2', 'parameter name 3'}, --
--------------------------------------------------------------------------------
cfg.parameters = {
-- The nocat and categories parameter suppress
-- categorisation. They are used with Module:Yesno, and work as follows:
--
-- cfg.nocat:
-- Result of yesno() Effect
-- true Categorisation is suppressed
-- false Categorisation is allowed, and
-- the blacklist check is skipped
-- nil Categorisation is allowed
--
-- cfg.categories:
-- Result of yesno() Effect
-- true Categorisation is allowed, and
-- the blacklist check is skipped
-- false Categorisation is suppressed
-- nil Categorisation is allowed
nocat = 'nocat',
categories = 'categories',
-- The parameter name for the legacy "category2" parameter. This skips the
-- blacklist if set to the cfg.category2Yes value, and suppresses
-- categorisation if present but equal to anything other than
-- cfg.category2Yes or cfg.category2Negative.
category2 = 'category2',
-- cfg.subpage is the parameter name to specify how to behave on subpages.
subpage = 'subpage',
-- The parameter for data to return in all namespaces.
all = 'all',
-- The parameter name for data to return if no data is specified for the
-- namespace that is detected.
other = 'other',
-- The parameter name used to specify a page other than the current page;
-- used for testing and demonstration.
demopage = 'page',
}
--------------------------------------------------------------------------------
-- Parameter values --
-- These are set values that can be used with certain parameters. Only one --
-- value can be specified, like this: --
-- --
-- cfg.foo = 'value name' -- --
--------------------------------------------------------------------------------
-- The following settings are used with the cfg.category2 parameter. Setting
-- cfg.category2 to cfg.category2Yes skips the blacklist, and if cfg.category2
-- is present but equal to anything other than cfg.category2Yes or
-- cfg.category2Negative then it supresses cateogrisation.
cfg.category2Yes = 'yes'
cfg.category2Negative = '¬'
-- The following settings are used with the cfg.subpage parameter.
-- cfg.subpageNo is the value to specify to not categorise on subpages;
-- cfg.subpageOnly is the value to specify to only categorise on subpages.
cfg.subpageNo = 'no'
cfg.subpageOnly = 'only'
--------------------------------------------------------------------------------
-- Default namespaces --
-- This is a table of namespaces to categorise by default. The keys are the --
-- namespace numbers. --
--------------------------------------------------------------------------------
cfg.defaultNamespaces = {
[ 0] = true, -- main
[ 6] = true, -- file
[ 12] = true, -- help
[ 14] = true, -- category
[100] = true, -- portal
[108] = true, -- book
}
--------------------------------------------------------------------------------
-- Wrappers --
-- This is a wrapper template or a list of wrapper templates to be passed to --
-- [[Module:Arguments]]. --
--------------------------------------------------------------------------------
cfg.wrappers = 'Template:Category handler'
--------------------------------------------------------------------------------
-- End configuration data --
--------------------------------------------------------------------------------
return cfg -- Don't edit this line.
373cd107b13a5b00e6a1b7e66a749f12502c849d
Модуль:Category handler/blacklist
828
75
122
2017-08-01T19:26:43Z
ruwiki>Q-bit array
0
Защитил «[[Модуль:Category handler/blacklist]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только админис…
Scribunto
text/plain
-- This module contains the blacklist used by [[Module:Category handler]].
-- Pages that match Lua patterns in this list will not be categorised unless
-- categorisation is explicitly requested.
return {
'^Main Page$', -- don't categorise the main page.
-- Don't categorise the following pages or their subpages.
-- "%f[/\0]" matches if the next character is "/" or the end of the string.
'^Wikipedia:Cascade%-protected items%f[/\0]',
'^User:UBX%f[/\0]', -- The userbox "template" space.
'^User talk:UBX%f[/\0]',
-- Don't categorise subpages of these pages, but allow
-- categorisation of the base page.
'^Wikipedia:Template messages/.*$',
'/[aA]rchive' -- Don't categorise archives.
}
c84948ad9808d5d323408d5d10d5652f748a0550
Модуль:Category handler
828
31
414
2017-08-01T19:26:45Z
ruwiki>Q-bit array
0
Защитил «[[Модуль:Category handler]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только администрато…
Scribunto
text/plain
--------------------------------------------------------------------------------
-- --
-- CATEGORY HANDLER --
-- --
-- This module implements the {{category handler}} template in Lua, --
-- with a few improvements: all namespaces and all namespace aliases --
-- are supported, and namespace names are detected automatically for --
-- the local wiki. This module requires [[Module:Namespace detect]] --
-- and [[Module:Yesno]] to be available on the local wiki. It can be --
-- configured for different wikis by altering the values in --
-- [[Module:Category handler/config]], and pages can be blacklisted --
-- from categorisation by using [[Module:Category handler/blacklist]]. --
-- --
--------------------------------------------------------------------------------
-- Load required modules
local yesno = require('Module:Yesno')
-- Lazily load things we don't always need
local mShared, mappings
local p = {}
--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------
local function trimWhitespace(s, removeBlanks)
if type(s) ~= 'string' then
return s
end
s = s:match('^%s*(.-)%s*$')
if removeBlanks then
if s ~= '' then
return s
else
return nil
end
else
return s
end
end
--------------------------------------------------------------------------------
-- CategoryHandler class
--------------------------------------------------------------------------------
local CategoryHandler = {}
CategoryHandler.__index = CategoryHandler
function CategoryHandler.new(data, args)
local obj = setmetatable({ _data = data, _args = args }, CategoryHandler)
-- Set the title object
do
local pagename = obj:parameter('demopage')
local success, titleObj
if pagename then
success, titleObj = pcall(mw.title.new, pagename)
end
if success and titleObj then
obj.title = titleObj
if titleObj == mw.title.getCurrentTitle() then
obj._usesCurrentTitle = true
end
else
obj.title = mw.title.getCurrentTitle()
obj._usesCurrentTitle = true
end
end
-- Set suppression parameter values
for _, key in ipairs{'nocat', 'categories'} do
local value = obj:parameter(key)
value = trimWhitespace(value, true)
obj['_' .. key] = yesno(value)
end
do
local subpage = obj:parameter('subpage')
local category2 = obj:parameter('category2')
if type(subpage) == 'string' then
subpage = mw.ustring.lower(subpage)
end
if type(category2) == 'string' then
subpage = mw.ustring.lower(category2)
end
obj._subpage = trimWhitespace(subpage, true)
obj._category2 = trimWhitespace(category2) -- don't remove blank values
end
return obj
end
function CategoryHandler:parameter(key)
local parameterNames = self._data.parameters[key]
local pntype = type(parameterNames)
if pntype == 'string' or pntype == 'number' then
return self._args[parameterNames]
elseif pntype == 'table' then
for _, name in ipairs(parameterNames) do
local value = self._args[name]
if value ~= nil then
return value
end
end
return nil
else
error(string.format(
'invalid config key "%s"',
tostring(key)
), 2)
end
end
function CategoryHandler:isSuppressedByArguments()
return
-- See if a category suppression argument has been set.
self._nocat == true
or self._categories == false
or (
self._category2
and self._category2 ~= self._data.category2Yes
and self._category2 ~= self._data.category2Negative
)
-- Check whether we are on a subpage, and see if categories are
-- suppressed based on our subpage status.
or self._subpage == self._data.subpageNo and self.title.isSubpage
or self._subpage == self._data.subpageOnly and not self.title.isSubpage
end
function CategoryHandler:shouldSkipBlacklistCheck()
-- Check whether the category suppression arguments indicate we
-- should skip the blacklist check.
return self._nocat == false
or self._categories == true
or self._category2 == self._data.category2Yes
end
function CategoryHandler:matchesBlacklist()
if self._usesCurrentTitle then
return self._data.currentTitleMatchesBlacklist
else
mShared = mShared or require('Module:Category handler/shared')
return mShared.matchesBlacklist(
self.title.prefixedText,
mw.loadData('Module:Category handler/blacklist')
)
end
end
function CategoryHandler:isSuppressed()
-- Find if categories are suppressed by either the arguments or by
-- matching the blacklist.
return self:isSuppressedByArguments()
or not self:shouldSkipBlacklistCheck() and self:matchesBlacklist()
end
function CategoryHandler:getNamespaceParameters()
if self._usesCurrentTitle then
return self._data.currentTitleNamespaceParameters
else
if not mappings then
mShared = mShared or require('Module:Category handler/shared')
mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData
end
return mShared.getNamespaceParameters(
self.title,
mappings
)
end
end
function CategoryHandler:namespaceParametersExist()
-- Find whether any namespace parameters have been specified.
-- We use the order "all" --> namespace params --> "other" as this is what
-- the old template did.
if self:parameter('all') then
return true
end
if not mappings then
mShared = mShared or require('Module:Category handler/shared')
mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData
end
for ns, params in pairs(mappings) do
for i, param in ipairs(params) do
if self._args[param] then
return true
end
end
end
if self:parameter('other') then
return true
end
return false
end
function CategoryHandler:getCategories()
local params = self:getNamespaceParameters()
local nsCategory
for i, param in ipairs(params) do
local value = self._args[param]
if value ~= nil then
nsCategory = value
break
end
end
if nsCategory ~= nil or self:namespaceParametersExist() then
-- Namespace parameters exist - advanced usage.
if nsCategory == nil then
nsCategory = self:parameter('other')
end
local ret = {self:parameter('all')}
local numParam = tonumber(nsCategory)
if numParam and numParam >= 1 and math.floor(numParam) == numParam then
-- nsCategory is an integer
ret[#ret + 1] = self._args[numParam]
else
ret[#ret + 1] = nsCategory
end
if #ret < 1 then
return nil
else
return table.concat(ret)
end
elseif self._data.defaultNamespaces[self.title.namespace] then
-- Namespace parameters don't exist, simple usage.
return self._args[1]
end
return nil
end
--------------------------------------------------------------------------------
-- Exports
--------------------------------------------------------------------------------
local p = {}
function p._exportClasses()
-- Used for testing purposes.
return {
CategoryHandler = CategoryHandler
}
end
function p._main(args, data)
data = data or mw.loadData('Module:Category handler/data')
local handler = CategoryHandler.new(data, args)
if handler:isSuppressed() then
return nil
end
return handler:getCategories()
end
function p.main(frame, data)
data = data or mw.loadData('Module:Category handler/data')
local args = require('Module:Arguments').getArgs(frame, {
wrappers = data.wrappers,
valueFunc = function (k, v)
v = trimWhitespace(v)
if type(k) == 'number' then
if v ~= '' then
return v
else
return nil
end
else
return v
end
end
})
return p._main(args, data)
end
return p
b74dd63857b24904ac452429b11213f18647471f
Модуль:Category handler/shared
828
74
120
2017-08-01T19:26:47Z
ruwiki>Q-bit array
0
Защитил «[[Модуль:Category handler/shared]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только админист…
Scribunto
text/plain
-- This module contains shared functions used by [[Module:Category handler]]
-- and its submodules.
local p = {}
function p.matchesBlacklist(page, blacklist)
for i, pattern in ipairs(blacklist) do
local match = mw.ustring.match(page, pattern)
if match then
return true
end
end
return false
end
function p.getParamMappings(useLoadData)
local dataPage = 'Module:Namespace detect/data'
if useLoadData then
return mw.loadData(dataPage).mappings
else
return require(dataPage).mappings
end
end
function p.getNamespaceParameters(titleObj, mappings)
-- We don't use title.nsText for the namespace name because it adds
-- underscores.
local mappingsKey
if titleObj.isTalkPage then
mappingsKey = 'talk'
else
mappingsKey = mw.site.namespaces[titleObj.namespace].name
end
mappingsKey = mw.ustring.lower(mappingsKey)
return mappings[mappingsKey] or {}
end
return p
d2d5de1a031e6ce97c242cbfa8afe7a92cb9eca5
Модуль:Category handler/data
828
69
110
2017-08-01T19:26:49Z
ruwiki>Q-bit array
0
Защитил «[[Модуль:Category handler/data]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только администр…
Scribunto
text/plain
-- This module assembles data to be passed to [[Module:Category handler]] using
-- mw.loadData. This includes the configuration data and whether the current
-- page matches the title blacklist.
local data = require('Module:Category handler/config')
local mShared = require('Module:Category handler/shared')
local blacklist = require('Module:Category handler/blacklist')
local title = mw.title.getCurrentTitle()
data.currentTitleMatchesBlacklist = mShared.matchesBlacklist(
title.prefixedText,
blacklist
)
data.currentTitleNamespaceParameters = mShared.getNamespaceParameters(
title,
mShared.getParamMappings()
)
return data
abbc68048ff698e88dda06b64ecf384bbf583120
Шаблон:(!
10
254
668
2017-08-01T19:30:34Z
ruwiki>Q-bit array
0
Защитил «[[Шаблон:(!]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только администраторы] (бес…
wikitext
text/x-wiki
<includeonly>{|</includeonly><noinclude><nowiki>{|</nowiki>{{Doc}}
</noinclude>
fc286c1b614a7c93a17dd6f17f52dba12b86e363
Шаблон:!)
10
255
670
2017-08-01T19:30:40Z
ruwiki>Q-bit array
0
Изменил уровень защиты «[[Шаблон:!)]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только админ…
wikitext
text/x-wiki
|}<noinclude>{{Doc}}
</noinclude>
c1895c0eccb60664bc4f2bd850d909b3c65739c3
Шаблон:Yesno
10
131
304
2017-08-01T19:30:50Z
ruwiki>Q-bit array
0
Защитил «[[Шаблон:Yesno]]»: критический шаблон ([Редактирование=только администраторы] (бессрочно) [Переименование=только администраторы] (бе…
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>#switch: {{<includeonly>safesubst:</includeonly>lc: {{{1|¬}}} }}
|no
|n
|нет
|false
|0 = {{{no|<!-- null -->}}}
| = {{{blank|{{{no|<!-- null -->}}}}}}
|¬ = {{{¬|}}}
|yes
|y
|да
|true
|1 = {{{yes|yes}}}
|#default = {{{def|{{{yes|yes}}}}}}
}}<noinclude>
{{Documentation}}
</noinclude>
4e236854c477d07a225c2ab6c016c389b133e8d3
Модуль:URL
828
265
691
2017-09-18T16:34:08Z
ruwiki>Jack who built the house
0
уточнение категоризации
Scribunto
text/plain
function startsWith( source, substring )
if mw.ustring.len( substring ) > mw.ustring.len( source ) then
return false
end
return mw.ustring.sub( source, 1, mw.ustring.len( substring ) ) == substring
end
p = {}
function formatUrlImpl( source, title, length )
local scheme, host, path
local postfix = ''
local arg1, arg2 = source, title
local isTestPage = mw.title.getCurrentTitle().prefixedText == 'Модуль:URL'
-- Две квадратные скобки подряд — [[вики-ссылка]] вместо [ссылки] — возвращаем вход как есть.
if string.find( arg1, "[[", 1, true ) then
local result = arg1
if not isTestPage then
result = result .. '[[Категория:Википедия:Статьи с вики-ссылкой, переданной в Модуль:URL]]'
if arg2 then
-- Если есть arg2, а мы распарсить ссылку не смогли, и значит заменить title не сможем корректно, это есть ошибка.
result = result .. '[[Категория:Википедия:Статьи с ошибочной работой Модуль:URL]]'
end
end
return result
end
-- Более одной квадратной скобки — скорее всего, задано более одного URL — тоже возвращаем как есть.
if select(2, string.gsub( arg1, "%[", "" )) > 1 then
local result = arg1
if not isTestPage then
result = result .. '[[Категория:Википедия:Статьи со сложным входом в Модуль:URL]]'
if arg2 then
-- Если есть arg2, а мы распарсить ссылку не смогли, и значит заменить title не сможем корректно, это есть ошибка.
result = result .. '[[Категория:Википедия:Статьи с ошибочной работой Модуль:URL]]'
end
end
return result
end
source = mw.text.trim( source, "%[%] " )
local titleDelimeterPosition = mw.ustring.find( source, " ", 1 )
if titleDelimeterPosition then
if not title or title == "" then
title = mw.ustring.sub( source, titleDelimeterPosition + 1 )
local postfixDelimeterPosition = mw.ustring.find( title, "%]", 1 )
if postfixDelimeterPosition then
postfix = mw.ustring.sub( title, postfixDelimeterPosition + 1 )
title = mw.ustring.sub( title, 1, postfixDelimeterPosition - 1 )
end
end
source = mw.ustring.sub( source, 1, titleDelimeterPosition - 1 )
end
local hostStartPosition
local schemeDelimeterPosition = mw.ustring.find( source, "://", 1, true )
if schemeDelimeterPosition then
scheme = mw.ustring.sub( source, 1, schemeDelimeterPosition + 2)
hostStartPosition = schemeDelimeterPosition + 3
elseif mw.ustring.find( source, "^//", 1 ) then
scheme = "//"
hostStartPosition = 3
elseif mw.ustring.find( source, "^mailto:", 1 ) then
scheme = "mailto:"
hostStartPosition = 8
elseif mw.ustring.find( source, "@", 1 ) then
scheme = "mailto:"
source = scheme .. source
hostStartPosition = 8
else
scheme = "http://"
source = scheme .. source
hostStartPosition = 8
end
if title then
local finds = mw.ustring.find( arg1, "[", 1, true )
if titleDelimeterPosition and finds and finds > titleDelimeterPosition + 1 then
-- Если titleDelimeterPosition промазал мимо скобки и нашел пробел раньше неё, к примеру "a [b c]",
-- то свернуть всю нашу хиромантию и выдать первый аргумент без изменений.
if arg2 == nil then
return arg1 .. (isTestPage and '' or '[[Категория:Википедия:Статьи со сложным входом в Модуль:URL]]')
-- Если есть arg2, а мы распарсить ссылку не смогли, и значит заменить title не сможем корректно, это есть ошибка.
-- С другой стороны, если arg2 нет, а arg1 очень сложный, то возможно это нормальный ход вещей,
-- и на вход в модуль дана уже очень сильно оформленная ссылка.
else
return arg1 .. (isTestPage and '' or '[[Категория:Википедия:Статьи с ошибочной работой Модуль:URL]]')
end
end
return '[' .. source .. ' ' .. title .. ']' .. postfix
end
local hostDelimeterPosition = mw.ustring.find( source, "/", hostStartPosition, true )
if hostDelimeterPosition then
host = mw.ustring.sub( source, hostStartPosition, hostDelimeterPosition - 1 )
if hostDelimeterPosition == mw.ustring.len( source ) then
path = nil
else
path = mw.ustring.sub( source, hostDelimeterPosition + 1 )
end
else
host = mw.ustring.sub( source, hostStartPosition )
end
-- post-split format options
if startsWith( host, 'www.' ) then
host = mw.ustring.sub( host, 5 )
end
host = mw.language.new( 'en' ):lc( host )
if path and path ~= '' and path ~= '/' then
local title = host .. '/' .. path
if length and #title > length then
title = host .. '/' .. mw.ustring.sub( path, 1, length - #title - 2 ) .. '…'
end
return '[' .. source .. ' ' .. title .. ']' .. postfix
else
return '[' .. source .. ' ' .. host .. ']' .. postfix
end
end
function p.formatUrl( frame )
local url = frame.args[1] or ''
local title = frame.args[2] or ''
local length = frame.args['length'] and tonumber( frame.args['length'] )
url = mw.text.trim( url )
title = mw.text.trim( title )
if url == '' then
return nil
end
if title == '' then
title = nil
end
return formatUrlImpl( url, title, length )
end
function p.formatUrlSingle( context, options, url )
url = mw.text.trim( url )
if url == '' then
return nil
end
local title = nil
if ( options['text'] and options['text'] ~= '' ) then
title = options['text']
end
local length = options['length'] and tonumber( options['length'] )
return formatUrlImpl( url, title, length )
end
return p
a991f879e135a472238c7f589e8d20d92a856d4d
Шаблон:Langi
10
123
288
2017-10-14T07:25:47Z
ruwiki>Jack who built the house
0
→ [[/doc]]
wikitext
text/x-wiki
<span lang="{{{1}}}" xml:lang="{{{1}}}" style="font-style:italic;">{{{2}}}</span><noinclude>{{doc}}</noinclude>
7bb9f9098c88e770b982402adf30a3bbf645aa4b
Шаблон:Lang-sv
10
177
396
2017-12-10T06:47:12Z
ruwiki>Dima st bk
0
langi
wikitext
text/x-wiki
[[шведский язык|швед.]] {{langi|sv|{{{1}}}}}<noinclude>{{doc|Lang/doc}}
</noinclude>
c4b5e81c6405972dcea4cc26ab77e99e9bd2021f
Модуль:Arguments
828
124
290
2018-01-12T21:01:04Z
ruwiki>Grain of sand
0
sandbox → песочница
Scribunto
text/plain
-- This module provides easy processing of arguments passed to Scribunto from
-- #invoke. It is intended for use by other Lua modules, and should not be
-- called from #invoke directly.
local libraryUtil = require('libraryUtil')
local checkType = libraryUtil.checkType
local arguments = {}
-- Generate four different tidyVal functions, so that we don't have to check the
-- options every time we call it.
local function tidyValDefault(key, val)
if type(val) == 'string' then
val = val:match('^%s*(.-)%s*$')
if val == '' then
return nil
else
return val
end
else
return val
end
end
local function tidyValTrimOnly(key, val)
if type(val) == 'string' then
return val:match('^%s*(.-)%s*$')
else
return val
end
end
local function tidyValRemoveBlanksOnly(key, val)
if type(val) == 'string' then
if val:find('%S') then
return val
else
return nil
end
else
return val
end
end
local function tidyValNoChange(key, val)
return val
end
local function matchesTitle(given, title)
local tp = type( given )
return (tp == 'string' or tp == 'number') and mw.title.new( given ).prefixedText == title
end
local translate_mt = { __index = function(t, k) return k end }
function arguments.getArgs(frame, options)
checkType('getArgs', 1, frame, 'table', true)
checkType('getArgs', 2, options, 'table', true)
frame = frame or {}
options = options or {}
--[[
-- Set up argument translation.
--]]
options.translate = options.translate or {}
if getmetatable(options.translate) == nil then
setmetatable(options.translate, translate_mt)
end
if options.backtranslate == nil then
options.backtranslate = {}
for k,v in pairs(options.translate) do
options.backtranslate[v] = k
end
end
if options.backtranslate and getmetatable(options.backtranslate) == nil then
setmetatable(options.backtranslate, {
__index = function(t, k)
if options.translate[k] ~= k then
return nil
else
return k
end
end
})
end
--[[
-- Get the argument tables. If we were passed a valid frame object, get the
-- frame arguments (fargs) and the parent frame arguments (pargs), depending
-- on the options set and on the parent frame's availability. If we weren't
-- passed a valid frame object, we are being called from another Lua module
-- or from the debug console, so assume that we were passed a table of args
-- directly, and assign it to a new variable (luaArgs).
--]]
local fargs, pargs, luaArgs
if type(frame.args) == 'table' and type(frame.getParent) == 'function' then
if options.wrappers then
--[[
-- The wrappers option makes Module:Arguments look up arguments in
-- either the frame argument table or the parent argument table, but
-- not both. This means that users can use either the #invoke syntax
-- or a wrapper template without the loss of performance associated
-- with looking arguments up in both the frame and the parent frame.
-- Module:Arguments will look up arguments in the parent frame
-- if it finds the parent frame's title in options.wrapper;
-- otherwise it will look up arguments in the frame object passed
-- to getArgs.
--]]
local parent = frame:getParent()
if not parent then
fargs = frame.args
else
local title = parent:getTitle():gsub('/песочница$', '')
local found = false
if matchesTitle(options.wrappers, title) then
found = true
elseif type(options.wrappers) == 'table' then
for _,v in pairs(options.wrappers) do
if matchesTitle(v, title) then
found = true
break
end
end
end
-- We test for false specifically here so that nil (the default) acts like true.
if found or options.frameOnly == false then
pargs = parent.args
end
if not found or options.parentOnly == false then
fargs = frame.args
end
end
else
-- options.wrapper isn't set, so check the other options.
if not options.parentOnly then
fargs = frame.args
end
if not options.frameOnly then
local parent = frame:getParent()
pargs = parent and parent.args or nil
end
end
if options.parentFirst then
fargs, pargs = pargs, fargs
end
else
luaArgs = frame
end
-- Set the order of precedence of the argument tables. If the variables are
-- nil, nothing will be added to the table, which is how we avoid clashes
-- between the frame/parent args and the Lua args.
local argTables = {fargs}
argTables[#argTables + 1] = pargs
argTables[#argTables + 1] = luaArgs
--[[
-- Generate the tidyVal function. If it has been specified by the user, we
-- use that; if not, we choose one of four functions depending on the
-- options chosen. This is so that we don't have to call the options table
-- every time the function is called.
--]]
local tidyVal = options.valueFunc
if tidyVal then
if type(tidyVal) ~= 'function' then
error(
"bad value assigned to option 'valueFunc'"
.. '(function expected, got '
.. type(tidyVal)
.. ')',
2
)
end
elseif options.trim ~= false then
if options.removeBlanks ~= false then
tidyVal = tidyValDefault
else
tidyVal = tidyValTrimOnly
end
else
if options.removeBlanks ~= false then
tidyVal = tidyValRemoveBlanksOnly
else
tidyVal = tidyValNoChange
end
end
--[[
-- Set up the args, metaArgs and nilArgs tables. args will be the one
-- accessed from functions, and metaArgs will hold the actual arguments. Nil
-- arguments are memoized in nilArgs, and the metatable connects all of them
-- together.
--]]
local args, metaArgs, nilArgs, metatable = {}, {}, {}, {}
setmetatable(args, metatable)
local function mergeArgs(tables)
--[[
-- Accepts multiple tables as input and merges their keys and values
-- into one table. If a value is already present it is not overwritten;
-- tables listed earlier have precedence. We are also memoizing nil
-- values, which can be overwritten if they are 's' (soft).
--]]
for _, t in ipairs(tables) do
for key, val in pairs(t) do
if metaArgs[key] == nil and nilArgs[key] ~= 'h' then
local tidiedVal = tidyVal(key, val)
if tidiedVal == nil then
nilArgs[key] = 's'
else
metaArgs[key] = tidiedVal
end
end
end
end
end
--[[
-- Define metatable behaviour. Arguments are memoized in the metaArgs table,
-- and are only fetched from the argument tables once. Fetching arguments
-- from the argument tables is the most resource-intensive step in this
-- module, so we try and avoid it where possible. For this reason, nil
-- arguments are also memoized, in the nilArgs table. Also, we keep a record
-- in the metatable of when pairs and ipairs have been called, so we do not
-- run pairs and ipairs on the argument tables more than once. We also do
-- not run ipairs on fargs and pargs if pairs has already been run, as all
-- the arguments will already have been copied over.
--]]
metatable.__index = function (t, key)
--[[
-- Fetches an argument when the args table is indexed. First we check
-- to see if the value is memoized, and if not we try and fetch it from
-- the argument tables. When we check memoization, we need to check
-- metaArgs before nilArgs, as both can be non-nil at the same time.
-- If the argument is not present in metaArgs, we also check whether
-- pairs has been run yet. If pairs has already been run, we return nil.
-- This is because all the arguments will have already been copied into
-- metaArgs by the mergeArgs function, meaning that any other arguments
-- must be nil.
--]]
if type(key) == 'string' then
key = options.translate[key]
end
local val = metaArgs[key]
if val ~= nil then
return val
elseif metatable.donePairs or nilArgs[key] then
return nil
end
for _, argTable in ipairs(argTables) do
local argTableVal = tidyVal(key, argTable[key])
if argTableVal ~= nil then
metaArgs[key] = argTableVal
return argTableVal
end
end
nilArgs[key] = 'h'
return nil
end
metatable.__newindex = function (t, key, val)
-- This function is called when a module tries to add a new value to the
-- args table, or tries to change an existing value.
if type(key) == 'string' then
key = options.translate[key]
end
if options.readOnly then
error(
'could not write to argument table key "'
.. tostring(key)
.. '"; the table is read-only',
2
)
elseif options.noOverwrite and args[key] ~= nil then
error(
'could not write to argument table key "'
.. tostring(key)
.. '"; overwriting existing arguments is not permitted',
2
)
elseif val == nil then
--[[
-- If the argument is to be overwritten with nil, we need to erase
-- the value in metaArgs, so that __index, __pairs and __ipairs do
-- not use a previous existing value, if present; and we also need
-- to memoize the nil in nilArgs, so that the value isn't looked
-- up in the argument tables if it is accessed again.
--]]
metaArgs[key] = nil
nilArgs[key] = 'h'
else
metaArgs[key] = val
end
end
local function translatenext(invariant)
local k, v = next(invariant.t, invariant.k)
invariant.k = k
if k == nil then
return nil
elseif type(k) ~= 'string' or not options.backtranslate then
return k, v
else
local backtranslate = options.backtranslate[k]
if backtranslate == nil then
-- Skip this one. This is a tail call, so this won't cause stack overflow
return translatenext(invariant)
else
return backtranslate, v
end
end
end
metatable.__pairs = function ()
-- Called when pairs is run on the args table.
if not metatable.donePairs then
mergeArgs(argTables)
metatable.donePairs = true
end
return translatenext, { t = metaArgs }
end
local function inext(t, i)
-- This uses our __index metamethod
local v = t[i + 1]
if v ~= nil then
return i + 1, v
end
end
metatable.__ipairs = function (t)
-- Called when ipairs is run on the args table.
return inext, t, 0
end
return args
end
return arguments
e6be8dfccffa2057c3d50700f350d8d140c1dbf9
Шаблон:Join
10
150
342
2018-06-13T14:41:38Z
ruwiki>Jack who built the house
0
перевод на модуль
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>#invoke:Separated entries|main|separator={{{separator|}}}}}<noinclude>
{{doc}}
<!-- Категории — на подстраницу /doc, интервики — в Викиданные. -->
</noinclude>
92bb17b5322d3ae0ceab93d4dad3d31810d47eb0
Шаблон:МестоСмерти
10
272
705
2018-06-13T20:22:03Z
ruwiki>WindEwriX
0
ставить [[Ш:Категория только в статьях]] под проверкой пространства имён в шаблоне на 100к включений это мощь
wikitext
text/x-wiki
<includeonly>{{#if:{{{3|}}}|[[{{{3}}}|{{{1}}}]]|{{#if:{{{1|}}}|[[{{{1}}}]]}}}}{{#if:{{NAMESPACE}}||{{#if:{{{1|}}}|[[Категория:Персоналии по алфавиту]][[Категория:Умершие {{#if:{{{2|}}}|{{{2}}}|в {{#ifeq:{{{1}}}|Ленинград|Санкт-Петербурге|{{Локатив|{{{1}}}}}}}}}]]}}}}</includeonly><noinclude> {{doc}}</noinclude>
c641a956648523b96cdbeaf3fe0e9c6a4644d4ad
Шаблон:Орден Ленина
10
274
709
2018-06-13T21:09:03Z
ruwiki>WindEwriX
0
/* top */удаление устаревшего шаблона с помощью [[Project:AWB|AWB]]
wikitext
text/x-wiki
{{#switch: {{{тип|}}}
| воинская часть = [[Файл:Leninorder.svg|40px|link=Орден Ленина|Орден Ленина {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Воинские части, награждённые орденом Ленина]]}}
| город = [[Файл:Leninorder.svg|40px|link=Орден Ленина|Орден Ленина {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Города, награждённые орденом Ленина]]}}
| регион = [[Файл:Leninorder.svg|40px|link=Орден Ленина|Орден Ленина {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Регионы, награждённые орденом Ленина]]}}
| организация = [[Файл:Leninorder.svg|40px|link=Орден Ленина|Орден Ленина {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Организации, награждённые орденом Ленина]]}}
| СМИ | сми = [[Файл:Leninorder.svg|40px|link=Орден Ленина|Орден Ленина {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:СМИ, награждённые орденом Ленина]]}}
| корабль = [[Файл:Leninorder.svg|40px|link=Орден Ленина|Орден Ленина {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Корабли, награждённые орденом Ленина]]}}
| [[Файл:SU Order of Lenin ribbon.svg|40px|link=Орден Ленина|Орден Ленина {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Кавалеры ордена Ленина]]}}
}}<noinclude>
{{doc}}
[[Категория:Шаблоны:Награды:СССР|Ленина]]
</noinclude>
2abac17c2226c03fa1628e5e5ecd11d7a997a10a
Шаблон:Скрытый
10
203
452
2018-06-14T09:27:38Z
ruwiki>Iniquity
0
Iniquity переименовал страницу [[Шаблон:Скрытый]] в [[Шаблон:Скрытый блок]]: унификация названий, в схеме [[Википедия:Форум/Архив/Предложения/2018/01#Шаблоны,_скрывающие_содержимое]]
wikitext
text/x-wiki
#перенаправление [[Шаблон:Скрытый блок]]
97cc939c1c8ece875b2ec360f85980bd6f1bbed7
Шаблон:Конец скрытого блока
10
199
444
2018-06-14T09:55:59Z
ruwiki>Iniquity
0
общая документация
wikitext
text/x-wiki
<includeonly></div></div></includeonly><noinclude>
{{doc|Шаблон:Начало скрытого блока/doc}}</noinclude>
2da6ac8eb0812fb4183a70b516009d40920e281f
Шаблон:Учёная степень
10
293
747
2018-06-15T22:14:30Z
ruwiki>Grain of sand
0
] потеряли
wikitext
text/x-wiki
<includeonly>{{#switch: {{{1|}}}
| кандидат = {{#switch: {{{2|}}}
| архитектуры = [[кандидат архитектуры]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты архитектуры]]}}
| биологических наук = [[кандидат биологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты биологических наук]]}}
| ветеринарных наук = [[кандидат ветеринарных наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты ветеринарных наук]]}}
| военно-морских наук = [[кандидат военно-морских наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты военно-морских наук]]}}
| военных наук = [[кандидат военных наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты военных наук]]}}
| географических наук = [[кандидат географических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты географических наук]]}}
| геолого-минералогических наук = [[кандидат геолого-минералогических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты геолого-минералогических наук]]}}
| искусствоведения = [[кандидат искусствоведения]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты искусствоведения]]}}
| исторических наук = [[кандидат исторических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты исторических наук]]}}
| культурологии = [[кандидат культурологии]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты культурологии]]}}
| медицинских наук = [[кандидат медицинских наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты медицинских наук]]}}
| педагогических наук = [[кандидат педагогических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты педагогических наук]]}}
| политических наук = [[кандидат политических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты политических наук]]}}
| психологических наук = [[кандидат психологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты психологических наук]]}}
| сельскохозяйственных наук = [[кандидат сельскохозяйственных наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты сельскохозяйственных наук]]}}
| социологических наук = [[кандидат социологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты социологических наук]]}}
| технических наук = [[кандидат технических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты технических наук]]}}
| фармацевтических наук = [[кандидат фармацевтических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты фармацевтических наук]]}}
| физико-математических наук = [[кандидат физико-математических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты физико-математических наук]]}}
| филологических наук = [[кандидат филологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты филологических наук]]}}
| философских наук = [[кандидат философских наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты философских наук]]}}
| химических наук = [[кандидат химических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты химических наук]]}}
| экономических наук = [[кандидат экономических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты экономических наук]][[Категория:Учёные по алфавиту]][[Категория:Экономисты по алфавиту]]}}
| юридических наук = [[кандидат юридических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты юридических наук]]}}
| [[кандидат наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты наук]]}}
}}
| доктор = {{#switch: {{{2|}}}
| архитектуры = [[доктор архитектуры]]{{#if:{{NAMESPACE}}||[[Категория:Доктора архитектуры]]}}
| биологических наук = [[доктор биологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора биологических наук]]}}
| ветеринарных наук = [[доктор ветеринарных наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора ветеринарных наук]]}}
| военно-морских наук = [[доктор военно-морских наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора военно-морских наук]]}}
| военных наук = [[доктор военных наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора военных наук]]}}
| географических наук = [[доктор географических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора географических наук]]}}
| геолого-минералогических наук = [[доктор геолого-минералогических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора геолого-минералогических наук]]}}
| искусствоведения = [[доктор искусствоведения]]{{#if:{{NAMESPACE}}||[[Категория:Доктора искусствоведения]]}}
| исторических наук = [[доктор исторических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора исторических наук]]}}
| культурологии = [[доктор культурологии]]{{#if:{{NAMESPACE}}||[[Категория:Доктора культурологии]]}}
| медицинских наук = [[доктор медицинских наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора медицинских наук]]}}
| педагогических наук = [[доктор педагогических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора педагогических наук]]}}
| политических наук = [[доктор политических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора политических наук]]}}
| психологических наук = [[доктор психологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора психологических наук]]}}
| сельскохозяйственных наук = [[доктор сельскохозяйственных наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора сельскохозяйственных наук]]}}
| социологических наук = [[доктор социологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора социологических наук]]}}
| технических наук = [[доктор технических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора технических наук]]}}
| фармацевтических наук = [[доктор фармацевтических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора фармацевтических наук]]}}
| физико-математических наук = [[доктор физико-математических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора физико-математических наук]]}}
| филологических наук = [[доктор филологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора филологических наук]]}}
| философских наук = [[доктор философских наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора философских наук]]}}
| химических наук = [[доктор химических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора химических наук]]}}
| экономических наук = [[доктор экономических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора экономических наук]][[Категория:Учёные по алфавиту]][[Категория:Экономисты по алфавиту]]}}
| юридических наук = [[доктор юридических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора юридических наук]]}}
| [[доктор наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора наук]]}}
}}
}}</includeonly><noinclude>{{doc}}</noinclude>
21fc4a364f53264639c70cc9807f6963ccb36b53
Шаблон:До символа
10
276
713
2018-07-11T11:21:59Z
ruwiki>A particle for world to form
0
Для возможности использовать подстановку.
wikitext
text/x-wiki
{{ {{{|safesubst:}}}#invoke:string2|bs|{{{1|}}}|{{{2|}}}|{{{from|1}}}}}<noinclude>{{doc}}</noinclude>
4cd51dc75d5f365cffac57c9577bd2b2f5c7cc3f
Шаблон:Без начала
10
165
372
2018-07-11T22:30:39Z
ruwiki>A particle for world to form
0
Для возможности использовать подстановку.
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>#ifeq:{{<includeonly>safesubst:</includeonly>Str_left|{{{1}}}|{{<includeonly>safesubst:</includeonly>#expr:{{<includeonly>safesubst:</includeonly>str len|{{{2}}}*}}-1}}}}*|{{{2}}}*|{{<includeonly>safesubst:</includeonly>Str_right|{{{1}}}|{{<includeonly>safesubst:</includeonly>#expr:{{<includeonly>safesubst:</includeonly>str len|{{{2}}}*}}-1}}}}|{{{1}}}}}<noinclude>{{doc}}</noinclude>
9fbca6f1fc236cb17fe77d76891e3f9c2afa2117
Шаблон:Str rightc
10
167
376
2018-07-11T22:33:58Z
ruwiki>A particle for world to form
0
Для возможности использовать подстановку.
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>Str sub|{{{1}}}|{{<includeonly>safesubst:</includeonly>#expr:{{<includeonly>safesubst:</includeonly>Str len|{{{1}}}}}-{{{2}}}}}|{{{2}}}}}<noinclude>{{doc}}</noinclude>
0401d500dcc2224d44867ba0ea1f6c0fbeb758a0
Шаблон:Str left
10
146
334
2018-07-11T22:39:12Z
ruwiki>A particle for world to form
0
Для возможности использовать подстановку.
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>padleft:|{{{2|1}}}|{{{1|}}}}}<noinclude>
{{doc}}
</noinclude>
c1f57b63826f4d455dcaec8d2c24a2b8268f42ec
Шаблон:Str sub
10
164
370
2018-09-29T20:45:02Z
ruwiki>TenBaseT
0
категории в документации
wikitext
text/x-wiki
<includeonly>{{{{{|safesubst:}}}#invoke:String|sublength|s={{{1}}}|i={{{2|0}}}|len={{{3|0}}}}}</includeonly><noinclude>
{{doc}}
</noinclude>
3043790f8803e868cf6097b475fd58ba742887fe
Модуль:Check for unknown parameters
828
86
146
2018-10-21T19:59:29Z
ruwiki>Well-Informed Optimist
0
Защитил страницу [[Модуль:Check for unknown parameters]]: критический шаблон или модуль ([Редактирование=только администраторы] (бессрочно) [Переименование=только администраторы] (бессрочно))
Scribunto
text/plain
-- This module may be used to compare the arguments passed to the parent
-- with a list of arguments, returning a specified result if an argument is
-- not on the list
local p = {}
local function trim(s)
return s:match('^%s*(.-)%s*$')
end
local function isnotempty(s)
return s and trim(s) ~= ''
end
function p.check (frame)
local args = frame.args
local pargs = frame:getParent().args
local ignoreblank = isnotempty(frame.args['ignoreblank'])
local showblankpos = isnotempty(frame.args['showblankpositional'])
local knownargs = {}
local unknown = frame.args['unknown'] or 'Found _VALUE_, '
local preview = frame.args['preview']
local values = {}
local res = {}
local regexps = {}
-- create the list of known args, regular expressions, and the return string
for k, v in pairs(args) do
if type(k) == 'number' then
v = trim(v)
knownargs[v] = 1
elseif k:find('^regexp[1-9][0-9]*$') then
table.insert(regexps, '^' .. v .. '$')
end
end
if isnotempty(preview) then
preview = '<div class="hatnote" style="color:red"><strong>Предупреждение:</strong> ' .. preview .. ' (это сообщение видно только при предпросмотре страницы).</div>'
elseif preview == nil then
preview = unknown
end
-- loop over the parent args, and make sure they are on the list
for k, v in pairs(pargs) do
if type(k) == 'string' and knownargs[k] == nil then
local knownflag = false
for i, regexp in ipairs(regexps) do
if mw.ustring.match(k, regexp) then
knownflag = true
break
end
end
if not knownflag and ( not ignoreblank or isnotempty(v) ) then
k = mw.ustring.gsub(k, '[^%w\-_ ]', '?')
table.insert(values, k)
end
elseif type(k) == 'number' and
knownargs[tostring(k)] == nil and
( showblankpos or isnotempty(v) )
then
local vlen = mw.ustring.len(v)
v = mw.ustring.sub(v, 1, (vlen < 25) and vlen or 25)
v = mw.ustring.gsub(v, '[^%w\-_ ]', '?')
table.insert(values, k .. ' = ' .. v .. ((vlen >= 25) and ' ...' or ''))
end
end
-- add resuls to the output tables
if #values > 0 then
if frame:preprocess( "{{REVISIONID}}" ) == "" then
unknown = preview
end
for k, v in pairs(values) do
if v == '' then
-- Fix odd bug for | = which gets stripped to the empty string and
-- breaks category links
v = ' '
end
local r = unknown:gsub('_VALUE_', v)
table.insert(res, r)
end
end
return table.concat(res)
end
function p.generate (frame)
local res = '{{#invoke:check for unknown parameters|check\n' ..
'|unknown=' .. frame.args['unknown'] .. '\n'
local checkerparams = {'ignoreblank', 'preview', 'showblankpositional'}
for _, v in pairs(checkerparams) do
if frame.args[v] then
res = res .. '|' .. v .. '=' .. frame.args[v] .. '\n'
end
end
local templatenamespace = frame.args[1]
local templatetitle = frame.args[2]
local pagepointer = mw.title.new(templatetitle, templatenamespace) -- именно такой порядок!
local text = pagepointer.getContent(pagepointer)
local params = {}
for param in string.gmatch(text, '\{\{\{([^\|\}]*)') do
params[#params+1] = mw.text.trim(param)
end
table.sort(params)
for k, v in pairs(params) do
if k == 1 or v ~= params[k-1] then
res = res .. '|' .. v
end
end
res = res .. '}}'
return res
end
return p
718ece7132a40acc051a3da4cdf668a76c02d10d
Шаблон:Lang-en2
10
283
727
2018-12-28T14:01:00Z
ruwiki>Dima st bk
0
Dima st bk переименовал страницу [[Шаблон:Langi-en2]] в [[Шаблон:Lang-en2]]: под стандарт
wikitext
text/x-wiki
{{langi|en|{{{1}}}}}<noinclude>
{{doc|Lang/doc}}
</noinclude>
0471cf4d45a13ece481915d5c3e55db65d6aca04
Шаблон:No-doc
10
187
418
2019-01-17T08:39:04Z
ruwiki>Dima st bk
0
Защитил страницу [[Шаблон:No-doc]]: критический шаблон или модуль ([Редактирование=только автоподтверждённые] (бессрочно) [Переименование=только администраторы] (бессрочно))
wikitext
text/x-wiki
{{#ifeq: {{SUBPAGENAME}} | doc
|| {{#if: {{#if: {{yesno|{{{nocat|}}}}} | x }}{{#switch: {{NAMESPACE}} | {{ns:10}} | {{ns:828}} = | x }}
|| {{{1|}}}
}}
}}<noinclude>{{doc}}</noinclude>
da013ca5b5f97f94bee392ff3a4488046f2ceac7
Шаблон:МестоРождения
10
270
701
2019-03-11T14:32:34Z
ruwiki>DonRumata
0
+ параметр nocat по запросу [[ВП:Ф-Т#Вопрос про nocat]]
wikitext
text/x-wiki
<includeonly>{{#if:{{{3|}}}|[[{{{3}}}|{{{1}}}]]|{{#if:{{{1|}}}|[[{{{1}}}]]}}}}{{#if:{{NAMESPACE}}{{{nocat|}}}||{{#if:{{{1|}}}|[[Категория:Персоналии по алфавиту]][[Категория:Родившиеся {{#if:{{{2|}}}|{{{2}}}|в {{#ifeq:{{{1}}}|Ленинград|Санкт-Петербурге|{{Локатив|{{{1}}}}}}}}}]]}}}}</includeonly><noinclude> {{doc}}</noinclude>
e03e5faeefe2ece8cfa949e62031800a70ec9773
Шаблон:Big
10
73
118
2019-04-25T13:33:41Z
ruwiki>QBA-bot
0
Защитил страницу [[Шаблон:Big]]: критический шаблон или модуль (каскадная защита) ([Редактирование=только автоподтверждённые] (бессрочно) [Переименование=только автоподтверждённые] (бессрочно))
wikitext
text/x-wiki
<span style="font-size:120%;">{{{1}}}</span><noinclude>
{{documentation}}
<!-- PLEASE ADD CATEGORIES TO THE /doc SUBPAGE, THANKS -->
</noinclude>
233a0192f59d7a0c6fef6b818e8d1c96d48295d2
Шаблон:Заготовка шаблона
10
298
757
2019-04-25T13:33:44Z
ruwiki>QBA-bot
0
Защитил страницу [[Шаблон:Заготовка шаблона]]: критический шаблон или модуль (каскадная защита) ([Редактирование=только автоподтверждённые] (бессрочно) [Переименование=только автоподтверждённые] (бессрочно))
wikitext
text/x-wiki
{{#invoke:TemplateDataDoc|generateBlank|{{#if:{{{1|}}}|{{{1}}}|{{BASEPAGENAME}}}}|description={{{описание|}}}}}<noinclude>{{doc}}</noinclude>
b451404244fd6898bc134564ddcb8941eca7f64a
Шаблон:Module other
10
95
161
2019-04-25T13:37:07Z
ruwiki>QBA-bot
0
Защитил страницу [[Шаблон:Module other]]: критический шаблон или модуль (каскадная защита) ([Редактирование=только автоподтверждённые] (бессрочно) [Переименование=только автоподтверждённые] (бессрочно))
wikitext
text/x-wiki
{{#switch:
<!--If no or empty "demospace" parameter then detect namespace-->
{{#if:{{{demospace|}}}
| {{lc: {{{demospace}}} }} <!--Use lower case "demospace"-->
| {{#ifeq:{{NAMESPACE}}|{{ns:Module}}
| module
| other
}}
}}
| module = {{{1|}}}
| other
| #default = {{{2|}}}
}}<!--End switch--><noinclude>
{{doc}}
<!-- Add categories and interwikis to the /doc subpage, not here! -->
</noinclude>
097d5ea3648fcbbe0ccd87e8f217c713e97922c7
Шаблон:Cross
10
205
458
2019-04-25T13:39:39Z
ruwiki>QBA-bot
0
Защитил страницу [[Шаблон:Cross]]: критический шаблон или модуль (каскадная защита) ([Редактирование=только автоподтверждённые] (бессрочно) [Переименование=только автоподтверждённые] (бессрочно))
wikitext
text/x-wiki
[[File:X mark.svg|{{{1|20}}}px|link=|alt=]]<span style="display:none">N</span><!--template:cross--><noinclude>
{{documentation}}
</noinclude>
ed4b409e99cfe41368cc2f86462c7f46372ac8bb
Шаблон:Tick
10
204
456
2019-04-25T13:40:45Z
ruwiki>QBA-bot
0
Защитил страницу [[Шаблон:Tick]]: критический шаблон или модуль (каскадная защита) ([Редактирование=только автоподтверждённые] (бессрочно) [Переименование=только автоподтверждённые] (бессрочно))
wikitext
text/x-wiki
#перенаправление [[Шаблон:Ok]]
f0887beb67bfbdc74fa97e8dd35f78474edfcefc
Шаблон:Demo
10
118
277
2019-04-25T13:40:59Z
ruwiki>QBA-bot
0
Защитил страницу [[Шаблон:Demo]]: критический шаблон или модуль (каскадная защита) ([Редактирование=только автоподтверждённые] (бессрочно) [Переименование=только автоподтверждённые] (бессрочно))
wikitext
text/x-wiki
{{#invoke:Demo|main}}<noinclude>{{documentation}}</noinclude>
e458e378477c6077a01987f334fdc73bee48512c
Модуль:Wikidata/count
828
163
368
2019-06-29T03:57:18Z
ruwiki>Dima st bk
0
Изменил уровень защиты [[Модуль:Wikidata/count]]: критический шаблон или модуль ([Редактирование=только администраторы] (бессрочно) [Переименование=только администраторы] (бессрочно))
Scribunto
text/plain
local p = {}
function p.getCount( context, options )
if ( not context ) then error( 'context not specified' ); end;
if ( not options ) then error( 'options not specified' ); end;
if ( not options.entity ) then error( 'options.entity missing' ); end;
local claims;
if options.property then -- TODO: Почему тут может не быть property?
claims = context.selectClaims( options, options.property );
end
if claims == nil then
return ''; --TODO error?
end
return table.getn(claims);
end
function p.isMultiple( context, options )
local count = p.getCount( context, options );
local multiple = '';
if( count ~= nil and count ~= '' and count > 1 ) then
multiple = 1;
end
return multiple;
end
return p
8ccf5dd7170a466674627b0afdf32c6bd2318154
Шаблон:Uses Wikidata
10
301
763
2019-08-10T23:17:15Z
ruwiki>Serhio Magpie
0
оформление кода при помощи [[u:JWBTH/ATP|скрипта]]
wikitext
text/x-wiki
{{Родственный проект
| проект = викиданные
| текст = Этот {{module other|модуль|шаблон}} использует {{#if: {{{раздел|{{{section|}}}}}}
| Свойства [[Викиданные|Викиданных]]; детальней см. [[#{{{раздел|{{{section|}}}}}}|§ {{{раздел|{{{section}}}}}}]].
| [[ВП:Викиданные{{!}}свойств{{#if:{{{2|}}}|а|о}} Викиданных]]:
}}
| внизу = {{#if: {{{раздел|{{{section|}}}}}} || <div class="plainlist"><ul>{{#invoke:Uses Wikidata|usesProperty}}</ul></div> }}
}}<noinclude>
{{doc}}
</noinclude>
5d62bf72bc1eea3b38bb5a9cd82eecf54b02fe45
Модуль:TableTools
828
125
292
2019-08-26T06:20:31Z
ruwiki>Serhio Magpie
0
Обновлено с https://en.wikipedia.org/w/index.php?title=Module:TableTools&oldid=887403551
Scribunto
text/plain
--[[
------------------------------------------------------------------------------------
-- TableTools --
-- --
-- This module includes a number of functions for dealing with Lua tables. --
-- It is a meta-module, meant to be called from other Lua modules, and should --
-- not be called directly from #invoke. --
------------------------------------------------------------------------------------
--]]
local libraryUtil = require('libraryUtil')
local p = {}
-- Define often-used variables and functions.
local floor = math.floor
local infinity = math.huge
local checkType = libraryUtil.checkType
local checkTypeMulti = libraryUtil.checkTypeMulti
--[[
------------------------------------------------------------------------------------
-- isPositiveInteger
--
-- This function returns true if the given value is a positive integer, and false
-- if not. Although it doesn't operate on tables, it is included here as it is
-- useful for determining whether a given table key is in the array part or the
-- hash part of a table.
------------------------------------------------------------------------------------
--]]
function p.isPositiveInteger(v)
if type(v) == 'number' and v >= 1 and floor(v) == v and v < infinity then
return true
else
return false
end
end
--[[
------------------------------------------------------------------------------------
-- isNan
--
-- This function returns true if the given number is a NaN value, and false
-- if not. Although it doesn't operate on tables, it is included here as it is
-- useful for determining whether a value can be a valid table key. Lua will
-- generate an error if a NaN is used as a table key.
------------------------------------------------------------------------------------
--]]
function p.isNan(v)
if type(v) == 'number' and tostring(v) == '-nan' then
return true
else
return false
end
end
--[[
------------------------------------------------------------------------------------
-- shallowClone
--
-- This returns a clone of a table. The value returned is a new table, but all
-- subtables and functions are shared. Metamethods are respected, but the returned
-- table will have no metatable of its own.
------------------------------------------------------------------------------------
--]]
function p.shallowClone(t)
local ret = {}
for k, v in pairs(t) do
ret[k] = v
end
return ret
end
--[[
------------------------------------------------------------------------------------
-- removeDuplicates
--
-- This removes duplicate values from an array. Non-positive-integer keys are
-- ignored. The earliest value is kept, and all subsequent duplicate values are
-- removed, but otherwise the array order is unchanged.
------------------------------------------------------------------------------------
--]]
function p.removeDuplicates(t)
checkType('removeDuplicates', 1, t, 'table')
local isNan = p.isNan
local ret, exists = {}, {}
for i, v in ipairs(t) do
if isNan(v) then
-- NaNs can't be table keys, and they are also unique, so we don't need to check existence.
ret[#ret + 1] = v
else
if not exists[v] then
ret[#ret + 1] = v
exists[v] = true
end
end
end
return ret
end
--[[
------------------------------------------------------------------------------------
-- numKeys
--
-- This takes a table and returns an array containing the numbers of any numerical
-- keys that have non-nil values, sorted in numerical order.
------------------------------------------------------------------------------------
--]]
function p.numKeys(t)
checkType('numKeys', 1, t, 'table')
local isPositiveInteger = p.isPositiveInteger
local nums = {}
for k, v in pairs(t) do
if isPositiveInteger(k) then
nums[#nums + 1] = k
end
end
table.sort(nums)
return nums
end
--[[
------------------------------------------------------------------------------------
-- affixNums
--
-- This takes a table and returns an array containing the numbers of keys with the
-- specified prefix and suffix. For example, for the table
-- {a1 = 'foo', a3 = 'bar', a6 = 'baz'} and the prefix "a", affixNums will
-- return {1, 3, 6}.
------------------------------------------------------------------------------------
--]]
function p.affixNums(t, prefix, suffix)
checkType('affixNums', 1, t, 'table')
checkType('affixNums', 2, prefix, 'string', true)
checkType('affixNums', 3, suffix, 'string', true)
local function cleanPattern(s)
-- Cleans a pattern so that the magic characters ()%.[]*+-?^$ are interpreted literally.
s = s:gsub('([%(%)%%%.%[%]%*%+%-%?%^%$])', '%%%1')
return s
end
prefix = prefix or ''
suffix = suffix or ''
prefix = cleanPattern(prefix)
suffix = cleanPattern(suffix)
local pattern = '^' .. prefix .. '([1-9]%d*)' .. suffix .. '$'
local nums = {}
for k, v in pairs(t) do
if type(k) == 'string' then
local num = mw.ustring.match(k, pattern)
if num then
nums[#nums + 1] = tonumber(num)
end
end
end
table.sort(nums)
return nums
end
--[[
------------------------------------------------------------------------------------
-- numData
--
-- Given a table with keys like ("foo1", "bar1", "foo2", "baz2"), returns a table
-- of subtables in the format
-- { [1] = {foo = 'text', bar = 'text'}, [2] = {foo = 'text', baz = 'text'} }
-- Keys that don't end with an integer are stored in a subtable named "other".
-- The compress option compresses the table so that it can be iterated over with
-- ipairs.
------------------------------------------------------------------------------------
--]]
function p.numData(t, compress)
checkType('numData', 1, t, 'table')
checkType('numData', 2, compress, 'boolean', true)
local ret = {}
for k, v in pairs(t) do
local prefix, num = mw.ustring.match(tostring(k), '^([^0-9]*)([1-9][0-9]*)$')
if num then
num = tonumber(num)
local subtable = ret[num] or {}
if prefix == '' then
-- Positional parameters match the blank string; put them at the start of the subtable instead.
prefix = 1
end
subtable[prefix] = v
ret[num] = subtable
else
local subtable = ret.other or {}
subtable[k] = v
ret.other = subtable
end
end
if compress then
local other = ret.other
ret = p.compressSparseArray(ret)
ret.other = other
end
return ret
end
--[[
------------------------------------------------------------------------------------
-- compressSparseArray
--
-- This takes an array with one or more nil values, and removes the nil values
-- while preserving the order, so that the array can be safely traversed with
-- ipairs.
------------------------------------------------------------------------------------
--]]
function p.compressSparseArray(t)
checkType('compressSparseArray', 1, t, 'table')
local ret = {}
local nums = p.numKeys(t)
for _, num in ipairs(nums) do
ret[#ret + 1] = t[num]
end
return ret
end
--[[
------------------------------------------------------------------------------------
-- sparseIpairs
--
-- This is an iterator for sparse arrays. It can be used like ipairs, but can
-- handle nil values.
------------------------------------------------------------------------------------
--]]
function p.sparseIpairs(t)
checkType('sparseIpairs', 1, t, 'table')
local nums = p.numKeys(t)
local i = 0
local lim = #nums
return function ()
i = i + 1
if i <= lim then
local key = nums[i]
return key, t[key]
else
return nil, nil
end
end
end
--[[
------------------------------------------------------------------------------------
-- size
--
-- This returns the size of a key/value pair table. It will also work on arrays,
-- but for arrays it is more efficient to use the # operator.
------------------------------------------------------------------------------------
--]]
function p.size(t)
checkType('size', 1, t, 'table')
local i = 0
for k in pairs(t) do
i = i + 1
end
return i
end
local function defaultKeySort(item1, item2)
-- "number" < "string", so numbers will be sorted before strings.
local type1, type2 = type(item1), type(item2)
if type1 ~= type2 then
return type1 < type2
else -- This will fail with table, boolean, function.
return item1 < item2
end
end
--[[
Returns a list of the keys in a table, sorted using either a default
comparison function or a custom keySort function.
]]
function p.keysToList(t, keySort, checked)
if not checked then
checkType('keysToList', 1, t, 'table')
checkTypeMulti('keysToList', 2, keySort, { 'function', 'boolean', 'nil' })
end
local list = {}
local index = 1
for key, value in pairs(t) do
list[index] = key
index = index + 1
end
if keySort ~= false then
keySort = type(keySort) == 'function' and keySort or defaultKeySort
table.sort(list, keySort)
end
return list
end
--[[
Iterates through a table, with the keys sorted using the keysToList function.
If there are only numerical keys, sparseIpairs is probably more efficient.
]]
function p.sortedPairs(t, keySort)
checkType('sortedPairs', 1, t, 'table')
checkType('sortedPairs', 2, keySort, 'function', true)
local list = p.keysToList(t, keySort, true)
local i = 0
return function()
i = i + 1
local key = list[i]
if key ~= nil then
return key, t[key]
else
return nil, nil
end
end
end
--[[
Returns true if all keys in the table are consecutive integers starting at 1.
--]]
function p.isArray(t)
checkType("isArray", 1, t, "table")
local i = 0
for k, v in pairs(t) do
i = i + 1
if t[i] == nil then
return false
end
end
return true
end
-- { "a", "b", "c" } -> { a = 1, b = 2, c = 3 }
function p.invert(array)
checkType("invert", 1, array, "table")
local map = {}
for i, v in ipairs(array) do
map[v] = i
end
return map
end
--[[
{ "a", "b", "c" } -> { ["a"] = true, ["b"] = true, ["c"] = true }
--]]
function p.listToSet(t)
checkType("listToSet", 1, t, "table")
local set = {}
for _, item in ipairs(t) do
set[item] = true
end
return set
end
--[[
Recursive deep copy function.
Preserves identities of subtables.
]]
local function _deepCopy(orig, includeMetatable, already_seen)
-- Stores copies of tables indexed by the original table.
already_seen = already_seen or {}
local copy = already_seen[orig]
if copy ~= nil then
return copy
end
if type(orig) == 'table' then
copy = {}
for orig_key, orig_value in pairs(orig) do
copy[deepcopy(orig_key, includeMetatable, already_seen)] = deepcopy(orig_value, includeMetatable, already_seen)
end
already_seen[orig] = copy
if includeMetatable then
local mt = getmetatable(orig)
if mt ~= nil then
local mt_copy = deepcopy(mt, includeMetatable, already_seen)
setmetatable(copy, mt_copy)
already_seen[mt] = mt_copy
end
end
else -- number, string, boolean, etc
copy = orig
end
return copy
end
function p.deepCopy(orig, noMetatable, already_seen)
checkType("deepCopy", 3, already_seen, "table", true)
return _deepCopy(orig, not noMetatable, already_seen)
end
--[[
Concatenates all values in the table that are indexed by a number, in order.
sparseConcat{ a, nil, c, d } => "acd"
sparseConcat{ nil, b, c, d } => "bcd"
]]
function p.sparseConcat(t, sep, i, j)
local list = {}
local list_i = 0
for _, v in p.sparseIpairs(t) do
list_i = list_i + 1
list[list_i] = v
end
return table.concat(list, sep, i, j)
end
--[[
-- This returns the length of a table, or the first integer key n counting from
-- 1 such that t[n + 1] is nil. It is similar to the operator #, but may return
-- a different value when there are gaps in the array portion of the table.
-- Intended to be used on data loaded with mw.loadData. For other tables, use #.
-- Note: #frame.args in frame object always be set to 0, regardless of
-- the number of unnamed template parameters, so use this function for
-- frame.args.
--]]
function p.length(t)
local i = 1
while t[i] ~= nil do
i = i + 1
end
return i - 1
end
function p.inArray(arr, valueToFind)
checkType("inArray", 1, arr, "table")
-- if valueToFind is nil, error?
for _, v in ipairs(arr) do
if v == valueToFind then
return true
end
end
return false
end
return p
fe918509f168332267834b3a6f5c219a9de5b2e7
Шаблон:Br separated entries
10
155
352
2019-08-30T23:08:35Z
ruwiki>Ле Лой
0
Защитил страницу [[Шаблон:Br separated entries]]: критический шаблон или модуль ([Редактирование=только администраторы] (бессрочно) [Переименование=только администраторы] (бессрочно))
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>#invoke:Separated entries|br}}<noinclude>
{{doc}}
</noinclude>
2113c3c6e95a84235b9f7a85e7ea17208e8f91df
Шаблон:Tp
10
216
480
2019-10-20T16:34:25Z
ruwiki>Helgo13
0
Helgo13 переименовал страницу [[Шаблон:Tp]] в [[Шаблон:Tlp]]: [[Википедия:К объединению/10 октября 2019#Шаблон:T → Шаблон:Tl, Шаблон:Tp → Шаблон:Tlp]]
wikitext
text/x-wiki
#перенаправление [[Шаблон:Tlp]]
d882ad71d959bf88034ac86b892a2686c44e6a87
Шаблон:T
10
161
364
2019-10-20T16:35:32Z
ruwiki>Helgo13
0
Helgo13 переименовал страницу [[Шаблон:T]] в [[Шаблон:Tl]]
wikitext
text/x-wiki
#перенаправление [[Шаблон:Tl]]
c0a76efe437d8a513d9f6878297f399a23944abd
545
364
2021-07-29T21:07:36Z
ruwiki>WerySkok
0
1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии.
wikitext
text/x-wiki
#перенаправление [[Шаблон:Tl]]
c0a76efe437d8a513d9f6878297f399a23944abd
Шаблон:Tl
10
162
366
2019-10-20T16:35:32Z
ruwiki>Helgo13
0
Helgo13 переименовал страницу [[Шаблон:T]] в [[Шаблон:Tl]]
wikitext
text/x-wiki
{{{{{|safesubst:}}}#invoke: Template call code | withoutParams }}<noinclude>{{doc}}</noinclude>
61fe4d068895a5e7e5802767f5d7df71a7561c57
Шаблон:Карточка/внизу
10
137
316
2019-11-13T23:18:52Z
ruwiki>Serhio Magpie
0
Перенесено в общие стили
wikitext
text/x-wiki
<includeonly>{{#if:{{{внизу|}}}|<tr><td colspan="2" class="infobox-below {{{класс_внизу|}}}" style="{{{стиль_внизу_общий|}}};{{{стиль_внизу|}}}">{{{внизу|}}}</td></tr>}}</includeonly><noinclude>
{{doc}}
</noinclude>
169fb2d10b0847c2fd677eda9f159ba99025198f
Шаблон:If-wikidata
10
148
338
2019-11-13T23:40:02Z
ruwiki>Serhio Magpie
0
+ from
wikitext
text/x-wiki
{{#switch:{{wikidata|{{{1|}}}|{{{2|}}}|plain={{{plain|true}}}|from={{{from|}}}|somevalue={{{somevalue|}}}|novalue={{{novalue|}}}}}|значение отсутствует|={{{4|}}}|#default={{{3}}}}}<noinclude>
{{doc}}
</noinclude>
a8a37fd2c4f1a266ec48783d7d0ad22cdcd812cb
Модуль:Карточка
828
83
140
2020-01-09T11:04:31Z
ruwiki>SADIQUI
0
Scribunto
text/plain
--
-- Модуль для реализации шаблона {{Карточка}}
--
local p = {}
local HtmlBuilder = require('Module:HtmlBuilder')
local args = {}
local origArgs
local argsAliases = {}
local root
local function union(t1, t2)
-- Возвращает объединение значений двух таблиц в виде последовательности.
local vals = {}
for k, v in pairs(t1) do
vals[v] = true
end
for k, v in pairs(t2) do
vals[v] = true
end
local ret = {}
for k, v in pairs(vals) do
table.insert(ret, k)
end
return ret
end
local function getArgNums(prefix)
-- Возвращает таблицу индексов существующих полей с заданным префиксом,
-- например, для префикса 'текст' и установленных 'текст1', 'текст2' и
-- 'текст5' возвращает {1, 2, 5}.
local nums = {}
for k, v in pairs(args) do
local num = tostring(k):match('^' .. prefix .. '([1-9]%d*)$')
if num then table.insert(nums, tonumber(num)) end
end
table.sort(nums)
return nums
end
local function addRow(rowArgs)
-- Добавляет строку в карточку (заголовок или метку/текст).
if rowArgs.header then
root
.tag('tr')
.addClass(rowArgs.rowclass)
.attr('id', rowArgs.rowid)
.tag('th')
.attr('colspan', 2)
.attr('id', rowArgs.headerid)
.addClass(rowArgs.class)
.addClass(args['класс_заголовков'])
.css('text-align', 'center')
.cssText(args['стиль_заголовков'])
.wikitext(rowArgs.header)
elseif rowArgs.data then
local row = root.tag('tr')
row.addClass(rowArgs.rowclass)
row.attr('id', rowArgs.rowid)
if rowArgs.label then
row
.tag('th')
.attr('scope', 'row')
.attr('id', rowArgs.labelid)
.cssText(args['стиль_меток'])
.wikitext(rowArgs.label)
.done()
end
local dataCell = row.tag('td')
if not rowArgs.label then
dataCell
.attr('colspan', 2)
.css('text-align', 'center')
end
dataCell
.attr('id', rowArgs.dataid)
.addClass(rowArgs.class)
.cssText(rowArgs.datastyle)
.newline()
.wikitext(rowArgs.data)
end
end
local function renderTitle()
if not args['название'] then return end
root
.tag('caption')
.addClass(args['класс_названия'])
.cssText(args['стиль_названия'])
.wikitext(args['название'])
end
local function renderAboveRow()
if not args['вверху'] then return end
root
.tag('tr')
.tag('th')
.attr('colspan', 2)
.addClass(args['класс_вверху'])
.css('text-align', 'center')
.css('font-size', '125%')
.css('font-weight', 'bold')
.cssText(args['стиль_вверху'])
.wikitext(args['вверху'])
end
local function renderAbove2Row()
if not args['вверху2'] then return end
root
.tag('tr')
.tag('th')
.attr('colspan', 2)
.addClass(args['класс_вверху2'])
.css('text-align', 'center')
.css('font-style', 'oblique')
.cssText(args['стиль_вверху2'])
.wikitext(args['вверху2'])
end
local function renderBelowRow()
if not args['внизу'] then return end
root
.tag('tr')
.tag('td')
.attr('colspan', 2)
.addClass(args['класс_внизу'])
.css('text-align', 'center')
.cssText(args['стиль_внизу'])
.newline()
.wikitext(args['внизу'])
end
local function renderSubheaders()
if args['подзаголовок'] then
args['подзаголовок1'] = args['подзаголовок']
end
if args['класс_ряда_подзаголовка'] then
args['класс_ряда_подзаголовка1'] = args['класс_ряда_подзаголовка']
end
local subheadernums = getArgNums('подзаголовок')
for k, num in ipairs(subheadernums) do
addRow({
data = args['подзаголовок' .. tostring(num)],
datastyle = args['стиль_подзаголовков'] or args['стиль_подзаголовка' .. tostring(num)],
class = args['класс_подзаголовков'],
rowclass = args['класс_ряда_подзаголовка' .. tostring(num)]
})
end
end
local function renderImages()
if args['изображение'] then
args['изображение1'] = args['изображение']
end
if args['подпись'] then
args['подпись1'] = args['подпись']
end
local imagenums = getArgNums('изображение')
for k, num in ipairs(imagenums) do
local caption = args['подпись' .. tostring(num)]
local data = HtmlBuilder.create().wikitext(args['изображение' .. tostring(num)])
if caption then
data
.tag('div')
.cssText(args['стиль_подписи'])
.wikitext(caption)
end
addRow({
data = tostring(data),
datastyle = args['стиль_изображения'],
class = args['класс_изображения'],
rowclass = args['класс_ряда_изображения' .. tostring(num)]
})
end
end
local function renderRows()
-- Объединяет индексы заголовков и текстовых строк карточки
-- и визуализирует их в правильном порядке через addRow.
local rownums = union(getArgNums('заголовок'), getArgNums('текст'))
table.sort(rownums)
for k, num in ipairs(rownums) do
addRow({
header = args['заголовок' .. tostring(num)],
label = args['метка' .. tostring(num)],
data = args['текст' .. tostring(num)],
datastyle = args['стиль_текста'],
class = args['класс' .. tostring(num)],
rowclass = args['класс_ряда' .. tostring(num)],
dataid = args['id_текста' .. tostring(num)],
labelid = args['id_метки' .. tostring(num)],
headerid = args['id_заголовка' .. tostring(num)],
rowid = args['id_ряда' .. tostring(num)]
})
end
end
local function renderNavBar()
if not args['имя'] then return end
root
.tag('tr')
.tag('td')
.attr('colspan', 2)
.css('text-align', 'right')
.wikitext(mw.getCurrentFrame():expandTemplate({
title = 'Tnavbar',
args = { args['имя'] }
}))
end
local function isSet(x)
-- Возвращает истину, если x задан и не пустой
-- Внимание: отличается от enwiki! В enwiki проверяется на равенство 'yes'
return x and x ~= ''
end
local function renderItalicTitle()
-- Внимание: отличается от enwiki. В enwiki ожидается yes или force, здесь работает любое значение
if isSet(args['заголовок_курсивом']) then
root.wikitext(mw.getCurrentFrame():expandTemplate({title = 'Заголовок курсивом'}))
end
end
local function renderTrackingCategories()
if not isSet(args.nocat) then
if #(getArgNums('текст')) == 0 and mw.title.getCurrentTitle().namespace == 0 then
root.wikitext('[[Категория:Статьи с карточкой без заполненных данных]]')
end
if isSet(args['внедрение']) and args['название'] then
root.wikitext('[[Категория:Статьи со встроенной карточкой и параметром названия]]')
end
end
end
local function _infobox()
-- Задание общей страктуры карточки с добавлением стилей
-- для карточек-потомков.
if not isSet(args['внедрение']) then
root = HtmlBuilder.create('table')
root
.addClass('infobox')
.addClass(args['класс_тела'])
if isSet(args['подкарточка']) then
root
.css('padding', '0')
.css('border', 'none')
.css('margin', '-2px')
.css('width', 'auto')
.css('min-width', '100%')
.css('font-size', '100%')
.css('clear', 'none')
.css('float', 'none')
.css('background-color', 'transparent')
end
-- Микроразметка
if isSet(args['микр_тела']) then
root
.attr('itemscope', 'itemscope')
.attr('itemtype', args['микр_тела'])
end
root
.cssText(args['стиль_тела'])
renderTitle()
renderAboveRow()
renderAbove2Row()
else
root = HtmlBuilder.create()
root
.wikitext(args['название'])
end
renderSubheaders()
renderImages()
renderRows()
renderBelowRow()
renderNavBar()
renderItalicTitle()
renderTrackingCategories()
return tostring(root)
end
local function preprocessSingleArg(argName)
-- Добавляет аргумент в таблицу аргументов, если он определён и не пустой.
-- Пустые аргументы не обрабатываются, как и в ParserFunctions.
if origArgs[argName] and origArgs[argName] ~= '' then
args[argName] = origArgs[argName]
end
end
local function translateArg(aliasArgName,localArgName)
-- Функция добавляет поддержку алиасов параметров (например, на другом языке)
-- Добавляем алиас параметра в таблицу алиасов
-- Для одного параметра может быть несколько алиасов
-- Нумерованные параметры(текст1 и т.д.) заносятся без номера
if not argsAliases[localArgName] then
argsAliases[localArgName] = {}
end
table.insert(argsAliases[localArgName], aliasArgName)
-- Пока для тестирования: значения алиасов добавляются в таблицу аргументов
-- Нумерованные параметры работать не будут
if origArgs[localArgName] and origArgs[localArgName] ~= '' then
-- параметр уже задан на локальном языке
else
-- если алиас задан и не пустой
if origArgs[aliasArgName] and origArgs[aliasArgName] ~= '' then
origArgs[localArgName] = origArgs[aliasArgName]
end
end
end
local function preprocessArgs(prefixTable, step)
-- Сохраняет параметры с заданными префиксами в таблицу args, последовательно обходя
-- аргументы в нужном порядке и с нужным шагом. Благодаря этому сноски и пр. появляются
-- в правильном порядке. prefixTable — массив таблиц, каждая из которых может содержать
-- два поля: поле-строку префикса (обязательно) и поле-таблицу зависимых параметров.
-- Эта функция всегда обрабатывает параметры с префиксом, но зависимые параметры
-- обрабатываются, только если параметр с префиксом задан и не пустой.
if type(prefixTable) ~= 'table' then
error("В качестве таблицы префиксов должна использоваться таблица", 2)
end
if type(step) ~= 'number' then
error("Недопустимый тип параметра шага", 2)
end
-- Проверка правильности данных и обработка параметров без суффиксов.
for i,v in ipairs(prefixTable) do
if type(v) ~= 'table' or type(v.prefix) ~= "string" or (v.depend and type(v.depend) ~= 'table') then
error('Недопустимая таблица префиксов preprocessArgs', 2)
end
preprocessSingleArg(v.prefix)
-- Зависимые параметры обрабатываются, только если параметр с префиксом задан и не пустой.
if args[v.prefix] and v.depend then
for j, dependValue in ipairs(v.depend) do
if type(dependValue) ~= 'string' then
error('Недопустимый тип зависимого параметра в таблице preprocessArgs')
end
preprocessSingleArg(dependValue)
end
end
end
-- Обход нумерованных аргументов.
local a = 1 -- Переменная-счётчик.
local moreArgumentsExist = true
while moreArgumentsExist == true do
moreArgumentsExist = false
for i = a, a + step - 1 do
for j,v in ipairs(prefixTable) do
local prefixArgName = v.prefix .. tostring(i)
if origArgs[prefixArgName] then
moreArgumentsExist = true -- Искать аргументы дальше, если был хотя бы один (в т. ч. пустой)
preprocessSingleArg(prefixArgName)
end
-- Обрабатываем зависимые аргументы, если определена таблица зависимостей,
-- а также задан не пустой аргумент с префиксом, либо обрабатывается
-- "префикс1" и "префикс" задан (например, "изображение1" является синонимом для "изображение").
if v.depend and (args[prefixArgName] or (i == 1 and args[v.prefix])) then
for j,dependValue in ipairs(v.depend) do
local dependArgName = dependValue .. tostring(i)
preprocessSingleArg(dependArgName)
end
end
end
end
a = a + step
end
end
function p.infobox(frame)
-- При запуске через #invoke аргументы передаются через стандартную систему.
-- При тестировании также можно передавать таблицу аргументов через frame.
if frame == mw.getCurrentFrame() then
origArgs = frame:getParent().args
else
origArgs = frame
end
-- Поддержка параметров из англовики
translateArg('child','внедрение')
translateArg('bodyclass','класс_тела')
translateArg('subbox','подкарточка')
translateArg('bodystyle','стиль_тела')
translateArg('title','название')
translateArg('titleclass','класс_названия')
translateArg('titlestyle','стиль_названия')
translateArg('above','вверху')
translateArg('aboveclass','класс_вверху')
translateArg('abovestyle','стиль_вверху')
translateArg('subheader','подзаголовок')
translateArg('subheaderrowstyle','стиль_подзаголовка')
translateArg('subheaderrowclass','класс_подзаголовка')
translateArg('subheaderstyle','стиль_подзаголовков')
translateArg('subheaderclass','класс_подзаголовков')
translateArg('image','изображение')
translateArg('caption','подпись')
translateArg('imagerowclass','класс_ряда_изображения')
translateArg('captionstyle','стиль_подписи')
translateArg('imagestyle','стиль_изображения')
translateArg('imageclass','класс_изображения')
translateArg('header','заголовок')
translateArg('data','текст')
translateArg('label','метка')
translateArg('rowclass','класс_ряда')
translateArg('class','класс')
translateArg('dataid','id_текста')
translateArg('labelid','id_метки')
translateArg('headerid','id_заголовка')
translateArg('rowid','id_ряда')
translateArg('headerclass','класс_заголовков')
translateArg('headerstyle','стиль_заголовков')
translateArg('labelstyle','стиль_меток')
translateArg('datastyle','стиль_текста')
translateArg('below','внизу')
translateArg('belowclass','класс_внизу')
translateArg('belowstyle','стиль_внизу')
translateArg('name','имя')
--translateArg('italic title','заголовок_курсивом')
--translateArg('','')
-- Параметры обрабатываются по направлению чтения карточки, чтобы
-- сноски и др. отображались в нужных местах. Параметры, зависящие
-- от других параметров, обрабатываются только при наличии других параметров,
-- чтобы в списке сносок не возникали нежелательные сноски.
preprocessSingleArg('внедрение')
preprocessSingleArg('класс_тела')
preprocessSingleArg('подкарточка')
preprocessSingleArg('стиль_тела')
preprocessSingleArg('название')
preprocessSingleArg('класс_названия')
preprocessSingleArg('стиль_названия')
preprocessSingleArg('вверху')
preprocessSingleArg('класс_вверху')
preprocessSingleArg('стиль_вверху')
preprocessSingleArg('вверху2')
preprocessSingleArg('класс_вверху2')
preprocessSingleArg('стиль_вверху2')
preprocessArgs({
{prefix = 'подзаголовок', depend = {'стиль_подзаголовка', 'класс_подзаголовка'}}
}, 10)
preprocessSingleArg('стиль_подзаголовков')
preprocessSingleArg('класс_подзаголовков')
preprocessArgs({
{prefix = 'изображение', depend = {'подпись', 'класс_ряда_изображения'}}
}, 10)
preprocessSingleArg('стиль_подписи')
preprocessSingleArg('стиль_изображения')
preprocessSingleArg('класс_изображения')
preprocessArgs({
{prefix = 'заголовок'},
{prefix = 'текст', depend = {'метка'}},
{prefix = 'класс_ряда'},
{prefix = 'класс'},
{prefix = 'id_текста'},
{prefix = 'id_метки'},
{prefix = 'id_заголовка'},
{prefix = 'id_ряда'}
}, 50)
preprocessSingleArg('класс_заголовков')
preprocessSingleArg('стиль_заголовков')
preprocessSingleArg('стиль_меток')
preprocessSingleArg('стиль_текста')
preprocessSingleArg('внизу')
preprocessSingleArg('класс_внизу')
preprocessSingleArg('стиль_внизу')
preprocessSingleArg('имя')
preprocessSingleArg('заголовок_курсивом')
preprocessSingleArg('nocat')
return _infobox()
end
return p
2c8d650c985ea4b045be261f1a7a32917dfba56f
Модуль:String2
828
279
719
2020-02-07T22:56:05Z
ruwiki>Serhio Magpie
0
+ ucfirst
Scribunto
text/plain
--[[
Кое-какие дополнительные функции для строк
]]
local M = {
bs=function(f)-- первый параметр до начала второго параметра (или до конца, если он не встретился)
--необяз. 3-й параметр - с какого по номеру (с 1) символа начинать поиск.
return mw.ustring.sub(f.args[1], 1, (mw.ustring.find(f.args[1],f.args[2],tonumber(f.args[3] or 1),true) or 0)-1)
end;
as=function(f)-- первый параметр после начала второго параметра
return mw.ustring.sub(f.args[1], (mw.ustring.find(f.args[1],f.args[2],1,true) or 0)+1)
end;
Tr=function(s,f,t,cf,df,sf)-- транслитерация первого параметра путём замены символов из второго параметра символами из третьего.
-- Отдельными параметрами можно передавать флаги c, d и s, как в Perl; диапазоны в замене не работают, только в левой части
-- (т.е. дефис надо передавать первым или последним). Второй результат - число заменённых символов
local r, l, l2 = {}, mw.ustring.len(f), mw.ustring.len(t);
for i = 1, l do
r[mw.ustring.sub(f,i,i)] = i<=l2 and mw.ustring.sub(t,i,i) or df and '' or mw.ustring.sub(t,l2,l2)
end
local n2=0;
local res, n = mw.ustring.gsub(
s,
('[%s%s]%s'):format(
cf and '^' or '',
f:gsub('%','%%'):gsub(']','%]'):gsub('^%^','%^'),
sf and '+' or ''
),
sf and function(cc)
n2 = n2+mw.ustring.len(cc)-1;
return mw.ustring.gsub(cc,'.',r)
end or r
)
return res, n+n2
end;
-- tr = function(f) return (M.Tr(f.args[1],f.args[2],f.args[3],f.args['c'],f.args['d'],f.args['s'])) end;-- транслитерировать
-- trс = function(f) return ({M.Tr(f.args[1],f.args[2],f.args[3],f.args['c'],f.args['d'],f.args['s'])})[2] end;-- посчитать символы
Trg = function(s,t,f,fi)-- Производит замену строк произвольной длины (если с fi, регистр не учитывает).
-- Приоритет - по порядку в таблицах.
for n,p in ipairs(t) do
t[n] = {fi and mw.ustring.upper(p) or p,mw.ustring.len(p)}
end
local r,i,l,N = {},1,mw.ustring.len(s),0
while i<=l do
(function()
for n,p in ipairs(t) do
if ( fi and mw.ustring.upper(mw.ustring.sub(s,i,i+p[2]-1)) or mw.ustring.sub(s,i,i+p[2]-1) ) == p[1] then
table.insert(r,f[n]);
i = i+p[2]; N=N+1;
return
end
end
table.insert(r,mw.ustring.sub(s,i,i));
i=i+1;
return
end)()
end
return table.concat(r),N
end;
trg = function(frame)--Работает с номерными аргументами шаблона,если задан параметр u, иначе со своими.
-- Заменяет в первом аргументе аргументы 2, 4, 6... на аргументы 3, 5, 7...
local tf, t, f, i= frame.args['u'] and frame.getParent() or f, {}, {}, 1;
while tf.args[2*i] do t[tf.args[2*i]]=tf.args[2*i+1] or '' end
return ( M.Trg(tf.args[1],t,f,(frame.args['i'] or '')~='') )
end;
join = function (f) --объединяет нумерованные аргументы вызвавшего шаблона
-- от from или 1 до to или первого отсутствующего
-- через первый параметр invoke. Последний элемент можно присоединять иначе, задав второй параметр.
-- По умолчанию ',' & 'и'
-- Если 3-й параметр invoke — "s", строки из пробелов игнорируются; если "_", игнорируются пустые строки
local t, tf, i = {}, f:getParent(), tonumber(f.args.from) or 1
local k,j,m = tonumber(f.args.to),i,f.args[3]
while k and i<=k or tf.args[i] do
if (
({
['_']=function(s)return s~=''end;
['s']=function(s)return not tostring(s):match("^%s*$")end
})[m] or function() return true end
)(tf.args[i]) then
t[j]=tf.args[i];
j=j+1
end;
i=i+1
end
return mw.text.listToText(t,f.args[1],f.args[2] or f.args[1])
end
}
function M.formatRound(frame) --форматирует число, чтобы оно имело order знаков после запятой
return string.format("%0."..frame.args[2].."f",tonumber(frame.args[1]));
end
-- если строка s содержит число, увеличивает первое такое число на n, иначе возращает пустую строку.
-- если число начинается на 0, то увеличенное число будет содержать по крайне мере столько цифр сколько исходное.
function M.increase(s, n)
local a,b,c = string.match(s, "([^0-9]*)([0-9]+)(.*)")
if b==nil then return s end
local num = tonumber(b) + n
if b:sub(1,1)=='0'
then b = string.format("%0"..b:len().."d", num)
else b=num
end
return a .. b .. c
end
function M.ucfirst(frame )
local s = mw.text.trim( frame.args[1] or "" )
local s1 = ""
-- if it's a list chop off and (store as s1) everything up to the first <li>
local lipos = string.find(s, "<li>" )
if lipos then
s1 = string.sub(s, 1, lipos + 3)
s = string.sub(s, lipos + 4)
end
-- s1 is either "" or the first part of the list markup, so we can continue
-- and prepend s1 to the returned string
local letterpos
if string.find(s, "^%[%[[^|]+|[^%]]+%]%]") then
-- this is a piped wikilink, so we capitalise the text, not the pipe
local _
_, letterpos = string.find(s, "|%A*%a") -- find the first letter after the pipe
else
letterpos = string.find(s, '%a')
end
if letterpos then
local first = string.sub(s, 1, letterpos - 1)
local letter = string.sub(s, letterpos, letterpos)
local rest = string.sub(s, letterpos + 1)
return s1 .. first .. string.upper(letter) .. rest
else
return s1 .. s
end
end
return M
1d51eb45a573b689485dad672c0968c18ec3b342
Шаблон:Карточка/официальное название
10
169
380
2020-02-29T12:06:43Z
ruwiki>Helgo13
0
Защитил страницу [[Шаблон:Карточка/официальное название]]: критический шаблон или модуль ([Редактирование=только администраторы] (бессрочно) [Переименование=только администраторы] (бессрочно))
wikitext
text/x-wiki
{{wikidata|p1448[language!:ru]|{{{1|}}}|separator=<br>|conjunction=<br>|monolingualLangTemplate=lang|from={{{from|}}}}}<noinclude>{{doc}}</noinclude>
708a700c58a199343531d8fb3eec7ee897e92732
Модуль:Wikidata/P512
828
286
733
2020-06-16T04:56:58Z
ruwiki>Ghuron
0
выключаем категоризацию для докторов философии https://ru.wikipedia.org/w/index.php?diff=107578910
Scribunto
text/plain
local p = {}
--[[
Функция формирует строку с викиразметкой для переданного свойства
Принимает: объект контекста для вызова форматтеров и таблицу настройек
Возвращает: вики-форматированную строку
]]
function p.formatAcademicDegree( context, options )
if ( not context ) then error( 'context not specified' ); end;
if ( not options ) then error( 'options not specified' ); end;
if ( not options.entity ) then error( 'options.entity missing' ); end;
local claims = context.selectClaims( options, options.property );
if (claims == nil) then
return ''
end
local blackList = p.getPreviousDegrees( claims )
local formattedClaims = {}
for i, claim in ipairs(claims) do
if (claim.mainsnak.datavalue and not blackList[claim.mainsnak.datavalue.value['numeric-id']]) then
local formattedStatement = context.formatStatement( options, claim )
if (formattedStatement) then
formattedStatement = '<span class="wikidata-claim"' ..
' data-wikidata-property-id="' ..
string.upper( options.property ) ..
'" data-wikidata-claim-id="' ..
claim.id .. '">' ..
formattedStatement .. '</span>'
if (claim.qualifiers) then
formattedStatement = formattedStatement ..
p.formatQualifier( context, options, claim.qualifiers.P585 )
end
formattedStatement = formattedStatement ..
p.formatCorrespondingCategory( claim )
table.insert( formattedClaims, formattedStatement )
end
end
end
-- создание текстовой строки со списком оформленых заявлений из таблицы
return mw.text.listToText( formattedClaims, options.separator, options.conjunction );
end
--[[
Функция помещает в скобки текст первого квалификатора из переданной таблицы
Принимает: объект контекста для вызова форматтеров, таблицу настроеки
и таблицу квалификаторов
Возвращает: отформатированная строка с квалификатором
]]
function p.formatQualifier( context, options, qualifiers )
if (qualifiers~=nil and qualifiers[1] ~= nil) then
return ' (' .. context.formatSnak( options, qualifiers[1] ) .. ')'
end
return ''
end
--[[
Функция формирует список соответствующих ученых степеней нижней ступени (P155)
Например, для "доктор искусствоведения" это будет "кандидат искусствоведения"
Принимает: объект таблицу сущностей - академических степеней персоны (P512)
Возвращает: объект таблицу идентификаторов степеней нижней ступени
]]
function p.getPreviousDegrees( claims )
-- Пока нет нормальной возможности загружать элементы c кэшем
-- снаружи Module:Wikidata, мы эти соответствия захардкодим (без Q)
local correspondingCandidates = {
[16698078] = 19610224, -- архитектор
[17281188] = 19610186, -- биолог
[17281187] = 19610187, -- ветеринар
[17281186] = 19610193, -- военный
[16698080] = 19610195, -- географ
[16698082] = 19610197, -- гео-мин
[17281180] = 18523814, -- искусствовед
[12101789] = 18523811, -- историк
[16698084] = 19610200, -- культуролог
[17281165] = 19610203, -- медик
[17281161] = 19610206, -- педагог
[12101787] = 4212319, -- политолог
[17281156] = 19610208, -- психолог
[17281153] = 19610210, -- сель-хоз
[17281152] = 19610212, -- социолог
[17281125] = 18071588, -- техник
[17281115] = 19610228, -- фармацевт
[17281097] = 18002832, -- физ-мат
[17281087] = 19603970, -- филолог
[17281084] = 19603972, -- философ
[17281079] = 19610312, -- химик
[17281072] = 17744738, -- экономист
[18745564] = 19610320 -- юрист
}
local previousElements = {}
for i, claim in ipairs(claims) do
if(claim.mainsnak.datavalue) then
local entityId = claim.mainsnak.datavalue.value['numeric-id']
if (entityId) then
if correspondingCandidates[entityId] then
previousElements[correspondingCandidates[entityId]] = true
end
end
end
end
return previousElements
end
--[[
Функция формирует вики-разметку категории, соответствующей ученой степени
Принимает: объект таблицу утверждения
Возвращает: строку оформленного текста либо пустую строку
]]
function p.formatCorrespondingCategory (claim)
if ( not claim ) then return '' end;
if ( not claim.mainsnak ) then return '' end;
if claim.mainsnak.datavalue.value['numeric-id'] == 752297 then return '' end
local label = mw.wikibase.label("Q" .. claim.mainsnak.datavalue.value['numeric-id'])
if not label then label = '' end
local result, changes = string.gsub(label, "доктор ", "Категория:Доктора ")
if (changes == 1) then
return '[[' .. result .. ']]'
end
result, changes = string.gsub(label, "кандидат ", "Категория:Кандидаты ")
if (changes == 1) then
return '[[' .. result .. ']]'
end
return ''
end
return p
dea2568f9f334dcfc745eca69d76f89255ac1b2c
Модуль:Separated entries
828
158
358
2020-07-05T06:33:20Z
ruwiki>Serhio Magpie
0
+ newline
Scribunto
text/plain
-- This module takes positional parameters as input and concatenates them with
-- an optional separator. The final separator (the "conjunction") can be
-- specified independently, enabling natural-language lists like
-- "foo, bar, baz and qux".
local compressSparseArray = require('Module:TableTools').compressSparseArray
local p = {}
function p._main(args)
local separator = args.separator
-- Decode (convert to Unicode) HTML escape sequences, such as " " for space.
and mw.text.decode(args.separator) or ''
local conjunction = args.conjunction and mw.text.decode(args.conjunction) or separator
-- Discard named parameters.
local values = compressSparseArray(args)
return mw.text.listToText(values, separator, conjunction)
end
local function makeInvokeFunction(separator, conjunction)
return function (frame)
local args = require('Module:Arguments').getArgs(frame)
args.separator = separator or args.separator
args.conjunction = conjunction or args.conjunction
return p._main(args)
end
end
p.main = makeInvokeFunction()
p.br = makeInvokeFunction('<br />')
p.newline = makeInvokeFunction('\n')
p.comma = makeInvokeFunction(mw.message.new('comma-separator'):plain())
return p
33a68f0a46d62c42b6523a548f0f881e82ecfe58
Шаблон:Wikidata number switch
10
134
310
2020-07-12T09:21:12Z
ruwiki>Serhio Magpie
0
Проверка - если ничего нет из первых трёх параметров, ничего и не выводить
wikitext
text/x-wiki
{{#if: {{{3|}}}
| {{#if: {{{5|}}} | {{{5|}}} | {{{3|}}} }}
| {{#if: {{{2|}}}
| {{#if: {{{4|}}} | {{{4|}}} | {{{2|}}} }}
| {{#if: {{{1|}}}
| {{#if: {{{4|}}}{{{5|}}}
| {{#if: {{wikidata|{{{1|}}}|property-module=Wikidata/count|property-function=isMultiple|from={{{from|}}}}} | {{{5|}}} | {{{4|}}} }}
| {{wikidata|{{{1|}}}|from={{{from|}}}}}
}}
}}
}}
}}<noinclude>
{{doc}}
</noinclude>
7541bb47e73905a8ee240baa1dab1801f9f7b166
Модуль:Uses Wikidata
828
303
767
2020-09-04T07:07:02Z
ruwiki>QBA-bot
0
Защитил страницу [[Модуль:Uses Wikidata]]: критический шаблон или модуль (каскадная защита) ([Редактирование=только автоподтверждённые] (бессрочно) [Переименование=только автоподтверждённые] (бессрочно))
Scribunto
text/plain
local p = {}
local function incat( name, label, dot )
local incat = ''
if not dot then dot = '' end
local pincat = mw.site.stats.pagesInCategory( name, all )
if pincat ~= 0 then incat = "[[:К:" .. name .. "|" .. label .. tostring( pincat ) .. "]]" .. dot end
return incat
end
local function trackingcats(p_num)
local result =
incat("ВП:" .. p_num .. ":використовується", "'''U:'''", "•") ..
incat("ВП:" .. p_num .. ":відсутня", "'''<s>U:'''", "</s>•") ..
incat("Вікідані:" .. p_num .. ":відсутня", "'''<s>D:'''", "</s>•") ..
incat("Вікідані:" .. p_num .. ":відрізняється", "'''↑↓:'''")
if result ~= "" then return "[<span></span>" .. result .. "]"
else return "" end
end
function p.usesProperty(frame)
local parent = frame.getParent(frame)
local result = ''
local ii = 1
while true do
local p_num = ""
if parent.args[ii] or frame.args[ii] then
p_num = mw.text.trim(string.upper(parent.args[ii] or frame.args[ii])) end
if p_num ~= "" then
local label = mw.wikibase.label(p_num) or "БЕЗ НАЗВИ"
result = result .. "<li><b><i>[[d:Property:" .. p_num .. "|<small>" ..
p_num .. "</small>:" .. label .. "]]</i></b> {[[d:Property talk:" ..
p_num .. "|обс]]•[[d:Special:WhatLinksHere/Property:" ..
p_num .. "|исп]]}" ..
trackingcats(p_num) .. "</li>"
ii = ii + 1
else break
end
end
return result
end
return p
8a066acc434e0611d04134bb82a5fdd9d4fb5f9f
Шаблон:Карточка/блок
10
157
356
2020-10-20T13:56:13Z
ruwiki>Wikisaurus
0
Wikisaurus переименовал страницу [[Шаблон:Фрагмент таблицы]] в [[Шаблон:Карточка/блок]]: унификация с другими шаблонами для создания частей карточки
wikitext
text/x-wiki
<includeonly>{{#invoke:Infobox|renderLines}}</includeonly><noinclude>{{doc}}</noinclude>
b76f4bc95a8a44fea1fa0f577d84111b51ce1385
Шаблон:Переписать шаблон
10
190
426
2020-10-20T14:22:06Z
ruwiki>Wikisaurus
0
wikitext
text/x-wiki
{{ombox
|type = style
|text = '''Этот шаблон следует переписать{{#if: {{{меташаблон|}}} | с использованием меташаблона {{tl|{{{меташаблон}}}}} }}.''' <div style="font-size:95%;">{{#if: {{{меташаблон|}}} | Использование меташаблонов позволяет более полно использовать возможности шаблонов (см. [[Википедия:Рекомендации по созданию шаблонов]])|См. также [[Википедия:Рекомендации по созданию шаблонов]].}}</div>
}}<includeonly>{{no-doc|nocat={{{nocat|}}}|{{#switch: {{lc: {{{меташаблон|}}} }}
| карточка = [[Категория:Википедия:Шаблоны для перевода на карточку]]
| навигационная таблица = [[Категория:Википедия:Шаблоны для перевода на навигационную таблицу]]
| статья проекта = [[Категория:Википедия:Шаблоны для перевода на статью проекта]]
| ае | административная единица = [[Категория:Википедия:Шаблоны для перевода на шаблон АЕ]]
| [[Категория:Википедия:Шаблоны к переработке]]
}}
{{#switch: {{lc: {{{меташаблон|}}} }}
| карточка | карточка персонажа | ае | административная единица | воинское формирование ссср | карточка/блок = [[Категория:Шаблоны-карточки по алфавиту]]
}}
}}</includeonly><noinclude>{{doc}}</noinclude>
cb8733e779fa70731f445053204e92dc5afa0ebb
Модуль:Transclude
828
144
330
2020-11-17T12:38:34Z
ruwiki>Wikisaurus
0
пропускать пустые параметры в forall и join
Scribunto
text/plain
local p={}
-- Вызывает внутренний шаблон с аргументами объемлющего шаблона
function p.call(frame)
local template = frame.args[1]
local args = frame:getParent().args
return frame:expandTemplate{ title=template, args=args }
end
-- Общая реализация для forall и call
local function forallImpl(args, separator, conjunction, func)
-- нумерованные ключи из args
local keys = {}
-- перебор в произвольном порядке, даже для нумерованных ключей
for key, value in pairs(args) do
if type(key) == 'number' and value and value ~= '' then
table.insert(keys, key)
end
end
table.sort(keys)
local results = {}
for _, key in ipairs(keys) do
local value = func(args[key])
table.insert(results, value)
end
return mw.text.listToText(results, separator, conjunction)
end
-- Вызывает внутренний шаблон, передавая ему нумерованные параметры объемлющего шаблона по-одному
function p.forall(frame)
local template = frame.args[1]
local separator = frame.args.separator or ''
local conjunction = frame.args.conjunction or separator
local args = frame:getParent().args
local func = function(value)
return frame:expandTemplate{ title = template, args = {value} } -- или другой frame?
end
return forallImpl(args, separator, conjunction, func)
end
-- Берёт нумерованные аргументы объемлющего шаблона и склеивает их в единую строку
function p.join(frame)
local separator = frame.args[1] or ''
local conjunction = frame.args[2] or separator
local args = frame:getParent().args
local func = function(value)
return value
end
return forallImpl(args, separator, conjunction, func)
end
-- Служебная функция: удаляет дубликаты из отсортированного массива с нумерованными индексами
local function deleteDuplicates(args)
local res = {}
for key, value in pairs(args) do
if args[key+1] ~= value then
table.insert(res, value)
end
end
return res
end
-- Вызывает внутренний шаблон несколько раз, передавая в него блоки аргументов объемлющего шаблона
function p.npc(frame)
local args = frame:getParent().args
local templateFrame = frame:getParent()
local template = frame.args[1]
-- определение, блоки аргументов с какими номерами нужны:
-- если в объемлющем шаблоне есть "параметр12" и в вызове модуля есть "параметр", то вызывается 12-й блок
local nums = {}
for key, _ in pairs(args) do
local main, num = string.match(key, '^(.-)%s*(%d*)$')
num = tonumber(num)
-- учитывать "параметр12", только если задано "параметр"
if num and frame.args[main] then
table.insert(nums, num)
end
end
table.sort(nums)
nums = deleteDuplicates(nums)
-- проходить по нужным номерам блоков по возрастанию и однократно
-- подставлять в шаблон:
-- 1. общие аргументы данного модуля
-- 2. аргументы объемлющего шаблона вида "параметр12" как "параметр" в 12-й блок
local results = {}
for _, blockNum in ipairs(nums) do
-- общие аргументы модуля, которые передаются в каждый блок
local blockArgs = mw.clone(frame.args)
-- metatable ломает expandTemplate
setmetatable(blockArgs, nil)
for key, value in pairs(args) do
local main, num = string.match(key, '^(.-)%s*(%d*)$')
num = tonumber(num)
-- передавать "параметр12" как "параметр" в 12-й блок, только если есть "параметр" в вызове модуля
if blockNum == num and frame.args[main] then
blockArgs[main] = value
end
end
local blockText = templateFrame:expandTemplate{ title=template; args=blockArgs }
table.insert(results, blockText)
end
return table.concat(results)
end
-- Действует аналогично forall по числовой переменной, изменяющейся (по умолчанию, от 1) до f.args[2].
function p.cycle(f)
local tf,ac,op=f:getParent(), {}, f.args.output or 'inline';
local sep='';
if op == 'newline' then
sep='\n';
end
for p,k in pairs(f.args) do
if type(p)=='number' then
if p>2 then ac[p-1]=k end
else ac[p]=k
end
end
local s,fh = f.args[2]:match('^%s*(%-?%d+)%s*%.%.') or 1,
f.args[2]:match('%.%.%s*(%S.*)%s*$') or f.args[2] or '';
fh=tonumber(fh) or fh:match('^%s*(.-)%s*$');
s=tonumber(s);
local acr={};
if not s then error('Начало цикла «'..s..'» — не число') end
local function dc(order)
local r=tf:expandTemplate{ title=f.args[1]; args={s,unpack(ac)} }
if order == 'desc' then
s=s-1;
else
s=s+1;
end
if r~='' then table.insert(acr,r); return r end
end
if type(fh)=='number' then
if fh > s then
while s<=fh do dc('asc') end
else
while s>=fh do dc('desc') end
end
elseif fh~='' then
while tf:expandTemplate{ title=fh; args={s,unpack(ac)} } do dc('asc') end
else
while dc('asc') do end
end
return table.concat(acr, sep)
end
return p
c17cfab4cebc23157f5ab8d18c7e4f5c273bfa59
Шаблон:Пример шаблона
10
300
761
2020-12-04T10:56:35Z
ruwiki>QBA-bot
0
Защитил страницу [[Шаблон:Пример шаблона]]: критический шаблон или модуль (каскадная защита) ([Редактирование=только автоподтверждённые] (бессрочно) [Переименование=только автоподтверждённые] (бессрочно))
wikitext
text/x-wiki
{{#invoke:TemplateDataDoc|generateExample|{{#if:{{{1|}}}|{{{1}}}|{{BASEPAGENAME}}}}}}<noinclude>{{doc}}</noinclude>
4675b6574c5d274f0525e41569d31a0a4881168f
Шаблон:Карточка/изображение
10
213
474
2021-01-23T04:16:05Z
ruwiki>Serhio Magpie
0
Класс «media-caption» для подписи
wikitext
text/x-wiki
<includeonly>{{#if:{{{1|}}}|
{{#switch:{{{1|}}}
|-=-
|none=
|нет=
|{{#switch:{{str left|{{{1|}}}|1}}
|[|<|{|={{{1|}}}
|[[Файл:{{{1|}}}|{{#if:{{{size|{{{2|}}}}}}|{{#ifeq:{{str rightc|{{{size|{{{2|}}}}}}|2}}|px|{{{size|{{{2|}}}}}}|{{#ifeq:{{str rightc|{{{size|{{{2|}}}}}}|3}}|пкс|{{{size|{{{2|}}}}}}|{{{size|{{{2|}}}}}}px}}}}|274x400px}}{{#if:{{{caption|}}}|{{!}}{{{caption|}}}}}|frameless{{#if:{{{border|}}}|{{!}}border}}{{#if:{{{alt|}}}|{{!}}alt={{{alt|}}}}}]]
}}{{#if:{{{caption|}}}
|<span class="media-caption" style="display:block;">{{{caption|}}}</span>
}}
}}
}}</includeonly><!--
-->{{#if: {{{2|}}} | [[Категория:Википедия:Страницы с использованием устаревшего формата параметра Карточка/изображение]] }}<!--
-->{{#ifeq: {{str find|{{{size|{{{2|}}}}}}|pxpx}} | -1 || [[Категория:Википедия:Изображение с pxpx в размере]] }}<noinclude>{{doc}}</noinclude>
c54dd8fbf131f3bc584add9cd834eea7b4f45e43
Модуль:InfoboxImage
828
84
142
2021-01-23T04:17:21Z
ruwiki>Serhio Magpie
0
Класс «media-caption» для подписи
Scribunto
text/plain
-- Inputs:
-- image - Can either be a bare filename (with or without the File:/Image: prefix) or a fully formatted image link
-- size - size to display the image
-- maxsize - maximum size for image
-- sizedefault - default size to display the image if size param is blank
-- alt - alt text for image
-- title - title text for image
-- border - set to yes if border
-- center - set to yes, if the image has to be centered
-- upright - upright image param
-- suppressplaceholder - if yes then checks to see if image is a placeholder and suppresses it
-- Outputs:
-- Formatted image.
-- More details available at the "Module:InfoboxImage/doc" page
local i = {};
local yesno = require('Module:Yesno');
local placeholder_image = {
"Blue - Replace this image female.svg",
"Blue - Replace this image male.svg",
"Female no free image yet.png",
"Flag of None (square).svg",
"Flag of None.svg",
"Flag of.svg",
"Green - Replace this image female.svg",
"Green - Replace this image male.svg",
"Image is needed female.svg",
"Image is needed male.svg",
"Location map of None.svg",
"Male no free image yet.png",
"Missing flag.png",
"No flag.svg",
"No free portrait.svg",
"No portrait (female).svg",
"No portrait (male).svg",
"Red - Replace this image female.svg",
"Red - Replace this image male.svg",
"Replace this image female (blue).svg",
"Replace this image female.svg",
"Replace this image male (blue).svg",
"Replace this image male.svg",
"Silver - Replace this image female.svg",
"Silver - Replace this image male.svg",
}
function i.IsPlaceholder(image)
-- change underscores to spaces
image = mw.ustring.gsub(image, "_", " ");
-- if image starts with [[ then remove that and anything after |
if mw.ustring.sub(image,1,2) == "[[" then
image = mw.ustring.sub(image,3);
image = mw.ustring.gsub(image, "([^|]*)|.*", "%1");
end
-- Trim spaces
image = mw.ustring.gsub(image, '^[ ]*(.-)[ ]*$', '%1');
-- remove file: or image: prefix if exists
if mw.ustring.lower(mw.ustring.sub(image,1,5)) == "file:" then
image = mw.ustring.sub(image,6);
end
if mw.ustring.lower(mw.ustring.sub(image,1,6)) == "image:" then
image = mw.ustring.sub(image,7);
end
-- Trim spaces
image = mw.ustring.gsub(image, '^[ ]*(.-)[ ]*$', '%1');
-- capitalise first letter
image = mw.ustring.upper(mw.ustring.sub(image,1,1)) .. mw.ustring.sub(image,2);
for i,j in pairs(placeholder_image) do
if image == j then
return true
end
end
return false
end
function i.InfoboxImage(frame)
local image = frame.args["image"];
if image == "" or image == nil then
return "";
end
if image == " " then
return image;
end
if frame.args["suppressplaceholder"] == "yes" then
if i.IsPlaceholder(image) == true then
return "";
end
end
if mw.ustring.lower(mw.ustring.sub(image,1,5)) == "http:" then
return "";
end
if mw.ustring.lower(mw.ustring.sub(image,1,6)) == "[http:" then
return "";
end
if mw.ustring.lower(mw.ustring.sub(image,1,7)) == "[[http:" then
return "";
end
if mw.ustring.lower(mw.ustring.sub(image,1,6)) == "https:" then
return "";
end
if mw.ustring.lower(mw.ustring.sub(image,1,7)) == "[https:" then
return "";
end
if mw.ustring.lower(mw.ustring.sub(image,1,8)) == "[[https:" then
return "";
end
if mw.ustring.sub(image,1,2) == "[[" then
-- search for thumbnail images and add to tracking cat if found
if mw.title.getCurrentTitle().namespace == 0 and (mw.ustring.find(image, "|%s*thumb%s*[|%]]") or mw.ustring.find(image, "|%s*thumbnail%s*[|%]]")) then
return image --.. "[[Категория:Страницы с миниатюрами в карточках]]";
else
return image;
end
elseif mw.ustring.sub(image,1,2) == "{{" and mw.ustring.sub(image,1,3) ~= "{{{" then
return image;
elseif mw.ustring.sub(image,1,1) == "<" then
return image;
elseif mw.ustring.sub(image,1,5) == mw.ustring.char(127).."UNIQ" then
-- Found strip marker at begining, so pass don't process at all
return image;
else
local result = "";
local size = frame.args["size"];
local maxsize = frame.args["maxsize"];
local sizedefault = frame.args["sizedefault"];
local alt = frame.args["alt"];
local title = frame.args["title"];
local border = yesno(frame.args["border"]);
local upright = frame.args["upright"] or "";
local center = yesno(frame.args["center"]);
local caption = frame.args["caption"];
-- remove file: or image: prefix if exists
if mw.ustring.lower(mw.ustring.sub(image,1,5)) == "file:" then
image = mw.ustring.sub(image,6);
end
if mw.ustring.lower(mw.ustring.sub(image,1,6)) == "image:" then
image = mw.ustring.sub(image,7);
end
if maxsize ~= "" and maxsize ~= nil then
-- if no sizedefault then set to maxsize
if sizedefault == "" or sizedefault == nil then
sizedefault = maxsize
end
-- check to see if size bigger than maxsize
if size ~= "" and size ~= nil then
local sizenumber = tonumber(mw.ustring.match(size,"%d*")) or 0;
local maxsizenumber = tonumber(mw.ustring.match(maxsize,"%d*"));
if sizenumber>maxsizenumber and maxsizenumber>0 then
size = maxsize;
end
end
end
-- add px to size if just a number
if (tonumber(size) or 0) > 0 then
size = size .. "px";
end
result = "[[File:" .. image;
if size ~= "" and size ~= nil then
result = result .. "|" .. size;
elseif sizedefault ~= "" and sizedefault ~= nil then
result = result .. "|" .. sizedefault;
else
result = result .. "|frameless";
end
if center then
result = result .. "|center"
end
if alt ~= "" and alt ~= nil then
result = result .. "|alt=" .. alt;
end
if border then
result = result .. "|border";
end
if upright ~= "" then
result = result .. "|upright=" .. upright;
end
if title ~= "" and title ~= nil then
result = result .. "|" .. title;
elseif alt ~= "" and alt ~= nil then
result = result .. "|" .. alt;
end
result = result .. "]]";
if caption ~= "" and caption ~= nil then
result = result .. '<span class="media-caption" style="display:block">' .. caption .. '</span>';
end
return result;
end
end
return i;
ec0754cf3050a84a661c48656d091d291822e37d
Модуль:Hash
828
168
378
2021-02-07T10:01:11Z
ruwiki>Grain of sand
0
+ list() для вывода списка доступных алгоритмов
Scribunto
text/plain
local getArgs = require('Module:Arguments').getArgs
local p = {}
local function inTable(table, value)
for k, v in pairs(table) do
if v == value then
return true
end
end
return false
end
function p.list(frame)
return table.concat(mw.hash.listAlgorithms(), '; ')
end
function p.main(frame)
local args = getArgs(frame, { frameOnly = true })
local algorithm
if not args[1] then
return '<span class="error">Не указана строка для хеширования.</span>'
end
if args[2] then
if not inTable(mw.hash.listAlgorithms(), args[2]) then
return '<span class="error">Алгоритм хеширования ' .. args[2] .. ' не поддерживается, или вы неточно указали его имя. Используйте функцию <kbd>mw.hash.listAlgorithms()</kbd> для получения списка доступных алгоритмов.</span>'
end
algorithm = args[2]
else
-- Алгоритм выбран из соображений быстродействия (см. [[:en:Fowler–Noll–Vo hash function]]),
-- 64-битная функция используется для уменьшения вероятности коллизий до пренебрежимо малой
-- величины. Возможно, есть лучшая опция — проверяйте.
algorithm = 'fnv164'
end
return mw.hash.hashValue(algorithm, args[1])
end
return p
5d18513e574435f191164695449a620b031f93ec
Шаблон:Module rating
10
94
454
2021-02-12T16:47:09Z
ruwiki>Grain of sand
0
Grain of sand переименовал страницу [[Шаблон:Module rating]] в [[Шаблон:Рейтинг модуля]]: русский язык
wikitext
text/x-wiki
#перенаправление [[Шаблон:Рейтинг модуля]]
0539367219fc11b0d7d42bed14b289f52d90e6f1
Модуль:Infocards/dateCat
828
278
717
2021-02-14T08:16:01Z
ruwiki>WindEwriX
0
Защитил страницу [[Модуль:Infocards/dateCat]]: критический шаблон или модуль: включён в [[Модуль:Wikidata/date]] и [[Модуль:Infocards]] ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно))
Scribunto
text/plain
local p = {}
p.categoryUnknownBirthDate = '[[Категория:Персоналии, чья дата рождения не установлена]]'
p.categoryUnknownDeathDate = '[[Категория:Персоналии, чья дата смерти не установлена]]'
p.categoryBigCurrentAge = '[[Категория:Персоналии с большим текущим возрастом]]' --бывш. [[Категория:Википедия:Статьи о персоналиях с большим текущим возрастом]]
p.categoryNegativeAge = '[[Категория:Персоналии с отрицательным возрастом]]'
-- p.categoryBigDeathAge = '[[Категория:Википедия:Статьи о персоналиях с большим возрастом во время смерти]]' //deleted -d.bratchuk 05-07-2016
p.categoryBiographiesOfLivingPersons = '[[Категория:Википедия:Биографии современников]]'
p.categoryRecentlyDeceased = '[[Категория:Персоналии, умершие менее года назад]]'
p.categoryManualWikification = '[[Категория:Википедия:Статьи с ручной викификацией дат в карточке]]'
p.categoryNoBirthDate = '[[Категория:Персоналии без указанной даты рождения]]' --бывш. [[Категория:Википедия:Персоны без указанной даты рождения]]
return p
6b27e44bc0a4aaafa42074ca16db92b13e4999d4
Шаблон:Doc/end
10
176
394
2021-02-14T18:18:13Z
ruwiki>Putnik
0
для модулей предзагрузка нормально не работает
wikitext
text/x-wiki
<includeonly></div>
</div><templatestyles src="Шаблон:Doc/styles.css" />{{#ifexpr: {{NAMESPACENUMBER}} mod 2 = 1 <!-- Например, [[Обсуждение MediaWiki:Robots.txt]] -->
| {{^|1em}}
| <div class="ts-doc-footer plainlinks">
{{#ifeq: {{str left|{{PAGENAME}}|9}}
| Песочница
|
| {{#ifeq: {{str rightc|{{PAGENAME}}|10}}
| /песочница
|
| Во избежание поломок страниц, использующих этот {{#ifeq: {{NAMESPACE}}
| Модуль
| модуль
| шаблон
}}, экспериментируйте в [[Википедия:Правка и тестирование шаблонов в песочнице|песочнице]] <small style="font-style:normal;">({{#ifexist: {{FULLPAGENAME}}/песочница
| [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit}} редактировать] {{!}} [{{fullurl:Special:ComparePages|page1={{FULLPAGENAMEE}}&page2={{FULLPAGENAMEE}}/песочница}} разница] {{#ifexist: {{FULLPAGENAME}}/тесты | {{!}} [[{{FULLPAGENAME}}/тесты|тесты]] }}
| {{#ifeq: {{NAMESPACE}} | Модуль | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit}} создать] | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit&preload=Шаблон:Doc/предзагрузка-песочница}} создать] {{!}} [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit&preload=Шаблон:Doc/зеркало}} зеркало] }}
}})</small> или {{#ifeq: {{NAMESPACE}}
| Модуль
| [[Модуль:Песочница|песочнице для модулей]]
| своём [[ВП:ЛП|личном пространстве]]
}}.<br>
}}
}}{{#ifexist: {{FULLPAGENAME}}/doc | Пожалуйста, добавляйте категории на подстраницу [[/doc]]. }}[[Special:PrefixIndex/{{FULLPAGENAME}}/|Подстраницы этого {{#ifeq: {{NAMESPACE}}
| Модуль
| модуля
| шаблона
}}]].
</div>
}}</includeonly><noinclude>{{doc}}</noinclude>
758a01a3d76e14ef14b2b0ee047ac47ddac8fd8e
Шаблон:Tnav
10
219
486
2021-02-28T17:42:07Z
ruwiki>Jack who built the house
0
дополнение
wikitext
text/x-wiki
{{t|{{{1|}}}|nav|comment={{{comment|}}}}}<noinclude>
{{doc-inline}}
Это — обёртка для шаблона {{t|tl}}, предназначенная для использования в блоках навигации. Она передаёт в него флаг <code>nav</code> и комментарий в параметре {{para|comment}}.
{{шаблоны для документирования}}
{{doc-end}}
[[Категория:Шаблоны:Ссылки на шаблоны]]
[[Категория:Шаблоны:Для навигационных шаблонов]]
</noinclude>
583d607aa213790ae32dda4018a413255493e42b
Модуль:Color contrast
828
151
344
2021-03-01T22:40:23Z
ruwiki>Grain of sand
0
local
Scribunto
text/plain
--
-- This module implements
-- {{Color contrast ratio}}
-- {{Greater color contrast ratio}}
-- {{ColorToLum}}
-- {{RGBColorToLum}}
--
local p = {}
local HTMLcolor = mw.loadData( 'Module:Color contrast/colors' )
local function sRGB ( v )
if (v <= 0.03928) then
v = v / 12.92
else
v = math.pow((v+0.055)/1.055, 2.4)
end
return v
end
local function rgbdec2lum( R, G, B )
if ( 0 <= R and R < 256 and 0 <= G and G < 256 and 0 <= B and B < 256 ) then
return 0.2126 * sRGB(R/255) + 0.7152 * sRGB(G/255) + 0.0722 * sRGB(B/255)
else
return ''
end
end
local function hsl2lum( h, s, l )
if ( 0 <= h and h < 360 and 0 <= s and s <= 1 and 0 <= l and l <= 1 ) then
local c = (1 - math.abs(2*l - 1))*s
local x = c*(1 - math.abs( math.fmod(h/60, 2) - 1) )
local m = l - c/2
local r, g, b = m, m, m
if( 0 <= h and h < 60 ) then
r = r + c
g = g + x
elseif( 60 <= h and h < 120 ) then
r = r + x
g = g + c
elseif( 120 <= h and h < 180 ) then
g = g + c
b = b + x
elseif( 180 <= h and h < 240 ) then
g = g + x
b = b + c
elseif( 240 <= h and h < 300 ) then
r = r + x
b = b + c
elseif( 300 <= h and h < 360 ) then
r = r + c
b = b + x
end
return rgbdec2lum(255*r, 255*g, 255*b)
else
return ''
end
end
local function color2lum( c )
if (c == nil) then
return ''
end
-- whitespace
c = c:match( '^%s*(.-)[%s;]*$' )
-- lowercase
c = c:lower()
-- first try to look it up
local L = HTMLcolor[c]
if (L ~= nil) then
return L
end
-- convert from hsl
if mw.ustring.match(c,'^hsl%([%s]*[0-9][0-9%.]*[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*%)$') then
local h, s, l = mw.ustring.match(c,'^hsl%([%s]*([0-9][0-9%.]*)[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*%)$')
return hsl2lum(tonumber(h), tonumber(s)/100, tonumber(l)/100)
end
-- convert from rgb
if mw.ustring.match(c,'^rgb%([%s]*[0-9][0-9]*[%s]*,[%s]*[0-9][0-9]*[%s]*,[%s]*[0-9][0-9]*[%s]*%)$') then
local R, G, B = mw.ustring.match(c,'^rgb%([%s]*([0-9][0-9]*)[%s]*,[%s]*([0-9][0-9]*)[%s]*,[%s]*([0-9][0-9]*)[%s]*%)$')
return rgbdec2lum(tonumber(R), tonumber(G), tonumber(B))
end
-- convert from rgb percent
if mw.ustring.match(c,'^rgb%([%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*%)$') then
local R, G, B = mw.ustring.match(c,'^rgb%([%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*%)$')
return rgbdec2lum(255*tonumber(R)/100, 255*tonumber(G)/100, 255*tonumber(B)/100)
end
-- remove leading # (if there is one) and whitespace
c = mw.ustring.match(c, '^[%s#]*([a-f0-9]*)[%s]*$')
-- split into rgb
local cs = mw.text.split(c or '', '')
if( #cs == 6 ) then
local R = 16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[2])
local G = 16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[4])
local B = 16*tonumber('0x' .. cs[5]) + tonumber('0x' .. cs[6])
return rgbdec2lum(R, G, B)
elseif ( #cs == 3 ) then
local R = 16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[1])
local G = 16*tonumber('0x' .. cs[2]) + tonumber('0x' .. cs[2])
local B = 16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[3])
return rgbdec2lum(R, G, B)
end
-- failure, return blank
return ''
end
function p._greatercontrast(args)
local bias = tonumber(args['bias'] or '0') or 0
local v1 = color2lum(args[1] or '')
local c2 = args[2] or '#FFFFFF'
local v2 = color2lum(c2)
local c3 = args[3] or '#000000'
local v3 = color2lum(c3)
local ratio1 = 0;
local ratio2 = 0;
if (type(v1) == 'number' and type(v2) == 'number') then
ratio1 = (v2 + 0.05)/(v1 + 0.05)
ratio1 = (ratio1 < 1) and 1/ratio1 or ratio1
end
if (type(v1) == 'number' and type(v3) == 'number') then
ratio2 = (v3 + 0.05)/(v1 + 0.05)
ratio2 = (ratio2 < 1) and 1/ratio2 or ratio2
end
return (ratio1 + bias > ratio2) and c2 or c3
end
function p._ratio(args)
local v1 = color2lum(mw.text.unstripNoWiki(args[1] or ''))
local v2 = color2lum(mw.text.unstripNoWiki(args[2] or ''))
if (type(v1) == 'number' and type(v2) == 'number') then
-- v1 should be the brighter of the two.
if v2 > v1 then
v1, v2 = v2, v1
end
return (v1 + 0.05)/(v2 + 0.05)
else
return args['error'] or '?'
end
end
function p._styleratio(args)
local style = (args[1] or ''):lower()
local bg, fg = 'white', '#202122'
local lum_bg, lum_fg = 1, 0.016
if args[2] then
local lum = color2lum(args[2])
if lum ~= '' then bg, lum_bg = args[2], lum end
end
if args[3] then
local lum = color2lum(args[3])
if lum ~= '' then fg, lum_fg = args[3], lum end
end
local slist = mw.text.split(style or '', ';')
for k = 1, #slist do
local s = slist[k]
local k, v = s:match( '^[%s]*([^:]-):([^:]-)[%s;]*$' )
k = k or ''
v = v or ''
if (k:match('^[%s]*(background)[%s]*$') or k:match('^[%s]*(background%-color)[%s]*$')) then
local lum = color2lum(v)
if( lum ~= '' ) then bg, lum_bg = v, lum end
elseif (k:match('^[%s]*(color)[%s]*$')) then
local lum = color2lum(v)
if( lum ~= '' ) then bg, lum_fg = v, lum end
end
end
if lum_bg > lum_fg then
return (lum_bg + 0.05)/(lum_fg + 0.05)
else
return (lum_fg + 0.05)/(lum_bg + 0.05)
end
end
function p.lum(frame)
return color2lum(frame.args[1] or frame:getParent().args[1])
end
function p.ratio(frame)
local args = frame.args[1] and frame.args or frame:getParent().args
return p._ratio(args)
end
function p.styleratio(frame)
local args = frame.args[1] and frame.args or frame:getParent().args
return p._styleratio(args)
end
function p.greatercontrast(frame)
local args = frame.args[1] and frame.args or frame:getParent().args
return p._greatercontrast(args)
end
return p
cce580326bee8eaf3c81df6c76c04a9a2909dfa2
Шаблон:Wikidata
10
261
683
2021-04-01T12:24:50Z
ruwiki>MBH
0
[[ВП:Откат|откат]] правок [[Special:Contribs/Lê Lợi (bot)|Lê Lợi (bot)]] ([[UT:Lê Lợi (bot)|обс.]]) к версии Wikisaurus
wikitext
text/x-wiki
<includeonly>{{#invoke:Wikidata|formatProperty|property={{{1|}}}|value={{{2|}}}}}</includeonly><noinclude>{{doc}}</noinclude>
9d3d422eca39504b018df6ec0bb047392a7aba7e
Модуль:String
828
138
318
2021-05-06T07:16:24Z
ruwiki>Alexei Kopylov
0
[[ВП:Откат|откат]] правок [[Special:Contribs/Alexei Kopylov|Alexei Kopylov]] ([[UT:Alexei Kopylov|обс.]]) к версии DonRumata
Scribunto
text/plain
--[[
This module is intended to provide access to basic string functions.
Most of the functions provided here can be invoked with named parameters,
unnamed parameters, or a mixture. If named parameters are used, Mediawiki will
automatically remove any leading or trailing whitespace from the parameter.
Depending on the intended use, it may be advantageous to either preserve or
remove such whitespace.
Global options
ignore_errors: If set to 'true' or 1, any error condition will result in
an empty string being returned rather than an error message.
error_category: If an error occurs, specifies the name of a category to
include with the error message. The default category is
[Category:Errors reported by Module String].
no_category: If set to 'true' or 1, no category will be added if an error
is generated.
Unit tests for this module are available at Module:String/tests.
]]
local str = {}
--[[
subcount
This function returns the count of substring in source string.
Usage:
{{#invoke:String|subcount|source_string|substring|plain_flag}}
OR
{{#invoke:String|subcount|s=source_string|pattern=substring|plain=plain_flag}}
Parameters
s: The string to search
pattern: The pattern or string to find within the string
plain: A flag indicating that the substring should be understood as plain
text. Defaults to true.
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the target string.
]]
function str.subcount( frame )
local new_args = str._getParameters( frame.args, {'s', 'pattern', 'plain'} );
local s = new_args['s'] or '';
local plain_flag = str._getBoolean( new_args['plain'] or true );
local pattern = new_args['pattern'] or '';
if s == '' or pattern == '' then
return 0;
end
if plain_flag then
pattern = str._escapePattern( pattern );
end
local _, count = mw.ustring.gsub(s, pattern, "")
return count;
end
--[[
len
This function returns the length of the target string.
Usage:
{{#invoke:String|len|target_string|}}
OR
{{#invoke:String|len|s=target_string}}
Parameters
s: The string whose length to report
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the target string.
]]
function str.len( frame )
local new_args = str._getParameters( frame.args, {'s'} );
local s = new_args['s'] or '';
return mw.ustring.len( s )
end
--[[
sub
This function returns a substring of the target string at specified indices.
Usage:
{{#invoke:String|sub|target_string|start_index|end_index}}
OR
{{#invoke:String|sub|s=target_string|i=start_index|j=end_index}}
Parameters
s: The string to return a subset of
i: The fist index of the substring to return, defaults to 1.
j: The last index of the string to return, defaults to the last character.
The first character of the string is assigned an index of 1. If either i or j
is a negative value, it is interpreted the same as selecting a character by
counting from the end of the string. Hence, a value of -1 is the same as
selecting the last character of the string.
If the requested indices are out of range for the given string, an error is
reported.
]]
function str.sub( frame )
local new_args = str._getParameters( frame.args, { 's', 'i', 'j' } );
local s = new_args['s'] or '';
local i = tonumber( new_args['i'] ) or 1;
local j = tonumber( new_args['j'] ) or -1;
local len = mw.ustring.len( s );
-- Convert negatives for range checking
if i < 0 then
i = len + i + 1;
end
if j < 0 then
j = len + j + 1;
end
if i > len or j > len or i < 1 or j < 1 then
return str._error( 'Значение индекса подстроки выходит за допустимые границы' );
end
if j < i then
return str._error( 'Неверный порядок индексов подстроки' );
end
return mw.ustring.sub( s, i, j )
end
--[[
This function implements that features of {{str sub old}} and is kept in order
to maintain these older templates.
]]
function str.sublength( frame )
local i = tonumber( frame.args.i ) or 0
local len = tonumber( frame.args.len )
return mw.ustring.sub( frame.args.s, i + 1, len and ( i + len ) )
end
--[[
match
This function returns a substring from the source string that matches a
specified pattern.
Usage:
{{#invoke:String|match|source_string|pattern_string|start_index|match_number|plain_flag|nomatch_output}}
OR
{{#invoke:String|pos|s=source_string|pattern=pattern_string|start=start_index
|match=match_number|plain=plain_flag|nomatch=nomatch_output}}
Parameters
s: The string to search
pattern: The pattern or string to find within the string
start: The index within the source string to start the search. The first
character of the string has index 1. Defaults to 1.
match: In some cases it may be possible to make multiple matches on a single
string. This specifies which match to return, where the first match is
match= 1. If a negative number is specified then a match is returned
counting from the last match. Hence match = -1 is the same as requesting
the last match. Defaults to 1.
plain: A flag indicating that the pattern should be understood as plain
text. Defaults to false.
nomatch: If no match is found, output the "nomatch" value rather than an error.
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from each string. In some circumstances this is desirable, in
other cases one may want to preserve the whitespace.
If the match_number or start_index are out of range for the string being queried, then
this function generates an error. An error is also generated if no match is found.
If one adds the parameter ignore_errors=true, then the error will be suppressed and
an empty string will be returned on any failure.
For information on constructing Lua patterns, a form of [regular expression], see:
* http://www.lua.org/manual/5.1/manual.html#5.4.1
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Ustring_patterns
]]
function str.match( frame )
local new_args = str._getParameters( frame.args, {'s', 'pattern', 'start', 'match', 'plain', 'nomatch'} );
local s = new_args['s'] or '';
local start = tonumber( new_args['start'] ) or 1;
local plain_flag = str._getBoolean( new_args['plain'] or false );
local pattern = new_args['pattern'] or '';
local match_index = math.floor( tonumber(new_args['match']) or 1 );
local nomatch = new_args['nomatch'];
if s == '' then
return str._error( 'Пустая строка поиска' );
end
if pattern == '' then
return str._error( 'Пустой шаблон поиска' );
end
if math.abs(start) < 1 or math.abs(start) > mw.ustring.len( s ) then
return str._error( 'Индекс начала поиска выходит за допустимые границы' );
end
if match_index == 0 then
return str._error( 'Индекс совпадения выходит за допустимые границы' );
end
if plain_flag then
pattern = str._escapePattern( pattern );
end
local result
if match_index == 1 then
-- Find first match is simple case
result = mw.ustring.match( s, pattern, start )
else
if start > 1 then
s = mw.ustring.sub( s, start );
end
local iterator = mw.ustring.gmatch(s, pattern);
if match_index > 0 then
-- Forward search
for w in iterator do
match_index = match_index - 1;
if match_index == 0 then
result = w;
break;
end
end
else
-- Reverse search
local result_table = {};
local count = 1;
for w in iterator do
result_table[count] = w;
count = count + 1;
end
result = result_table[ count + match_index ];
end
end
if result == nil then
if nomatch == nil then
return str._error( 'Совпадение не найдено' );
else
return nomatch;
end
else
return result;
end
end
--[[
pos
This function returns a single character from the target string at position pos.
Usage:
{{#invoke:String|pos|target_string|index_value}}
OR
{{#invoke:String|pos|target=target_string|pos=index_value}}
Parameters
target: The string to search
pos: The index for the character to return
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the target string. In some circumstances this is desirable, in
other cases one may want to preserve the whitespace.
The first character has an index value of 1.
If one requests a negative value, this function will select a character by counting backwards
from the end of the string. In other words pos = -1 is the same as asking for the last character.
A requested value of zero, or a value greater than the length of the string returns an error.
]]
function str.pos( frame )
local new_args = str._getParameters( frame.args, {'target', 'pos'} );
local target_str = new_args['target'] or '';
local pos = tonumber( new_args['pos'] ) or 0;
if pos == 0 or math.abs(pos) > mw.ustring.len( target_str ) then
return str._error( 'Значение индекса строки выходит за допустимые границы' );
end
return mw.ustring.sub( target_str, pos, pos );
end
--[[
str_find
This function duplicates the behavior of {{str_find}}, including all of its quirks.
This is provided in order to support existing templates, but is NOT RECOMMENDED for
new code and templates. New code is recommended to use the "find" function instead.
Returns the first index in "source" that is a match to "target". Indexing is 1-based,
and the function returns -1 if the "target" string is not present in "source".
Important Note: If the "target" string is empty / missing, this function returns a
value of "1", which is generally unexpected behavior, and must be accounted for
separatetly.
]]
function str.str_find( frame )
local new_args = str._getParameters( frame.args, {'source', 'target'} );
local source_str = new_args['source'] or '';
local target_str = new_args['target'] or '';
if target_str == '' then
return 1;
end
local start = mw.ustring.find( source_str, target_str, 1, true )
if start == nil then
start = -1
end
return start
end
--[[
find
This function allows one to search for a target string or pattern within another
string.
Usage:
{{#invoke:String|find|source_str|target_string|start_index|plain_flag}}
OR
{{#invoke:String|find|source=source_str|target=target_str|start=start_index|plain=plain_flag}}
Parameters
source: The string to search
target: The string or pattern to find within source
start: The index within the source string to start the search, defaults to 1
plain: Boolean flag indicating that target should be understood as plain
text and not as a Lua style regular expression, defaults to true
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the parameter. In some circumstances this is desirable, in
other cases one may want to preserve the whitespace.
This function returns the first index >= "start" where "target" can be found
within "source". Indices are 1-based. If "target" is not found, then this
function returns 0. If either "source" or "target" are missing / empty, this
function also returns 0.
This function should be safe for UTF-8 strings.
]]
function str.find( frame )
local new_args = str._getParameters( frame.args, {'source', 'target', 'start', 'plain' } );
local source_str = new_args['source'] or '';
local pattern = new_args['target'] or '';
local start_pos = tonumber(new_args['start']) or 1;
local plain = new_args['plain'] or true;
if source_str == '' or pattern == '' then
return 0;
end
plain = str._getBoolean( plain );
local start = mw.ustring.find( source_str, pattern, start_pos, plain )
if start == nil then
start = 0
end
return start
end
--[[
replace
This function allows one to replace a target string or pattern within another
string.
Usage:
{{#invoke:String|replace|source_str|pattern_string|replace_string|replacement_count|plain_flag}}
OR
{{#invoke:String|replace|source=source_string|pattern=pattern_string|replace=replace_string|
count=replacement_count|plain=plain_flag}}
Parameters
source: The string to search
pattern: The string or pattern to find within source
replace: The replacement text
count: The number of occurences to replace, defaults to all.
plain: Boolean flag indicating that pattern should be understood as plain
text and not as a Lua style regular expression, defaults to true
]]
function str.replace( frame )
local new_args = str._getParameters( frame.args, {'source', 'pattern', 'replace', 'count', 'plain' } );
local source_str = new_args['source'] or '';
local pattern = new_args['pattern'] or '';
local replace = new_args['replace'] or '';
local count = tonumber( new_args['count'] );
local plain = new_args['plain'] or true;
if source_str == '' or pattern == '' then
return source_str;
end
plain = str._getBoolean( plain );
if plain then
pattern = str._escapePattern( pattern );
replace = mw.ustring.gsub( replace, "%%", "%%%%" ); --Only need to escape replacement sequences.
end
local result;
if count ~= nil then
result = mw.ustring.gsub( source_str, pattern, replace, count );
else
result = mw.ustring.gsub( source_str, pattern, replace );
end
return result;
end
--[[
This function adds support for escaping parts of the patterns when using [plain=false].
]]
function str.escape( frame )
local new_args = str._getParameters( frame.args, {'pattern' } );
local pattern = new_args['pattern'] or '';
local result = '';
result = str._escapePattern( pattern );
return result;
end
--[[
Internal compare string function
]]
function str._strcmp(a , b)
local s1c = mw.ustring.gcodepoint( a );
local s2c = mw.ustring.gcodepoint( b );
while true do
local c1 = s1c();
local c2 = s2c();
if c1 == nil then
if c2 == nil then
return 0
else
return -1
end
else
if c2 ~= nil then
if c1 ~= c2 then
return c1 < c2 and -1 or 1
end
else
return 1
end
end
end
return 0
end
--[[
compare
This function compare two UTF-8 strings
Usage:
{{#invoke:String|compare|str1|str2}}
Returns:
0 - if strings are equal
1 - if st1 > str2
-1 - if str1 < str2
]]
function str.compare(frame)
local str1 = frame.args[1] or '';
local str2 = frame.args[2] or '';
return str._strcmp(str1 , str2)
end
--[[
simple function to pipe string.rep to templates.
]]
function str.rep( frame )
local repetitions = tonumber( frame.args[2] )
if not repetitions then
return str._error( 'функция rep ожидает число во втором параметре, а получено "' .. ( frame.args[2] or '' ) .. '"' )
end
return string.rep( frame.args[1] or '', repetitions )
end
--[[
Helper function that populates the argument list given that user may need to use a mix of
named and unnamed parameters. This is relevant because named parameters are not
identical to unnamed parameters due to string trimming, and when dealing with strings
we sometimes want to either preserve or remove that whitespace depending on the application.
]]
function str._getParameters( frame_args, arg_list )
local new_args = {};
local index = 1;
local value;
for i,arg in ipairs( arg_list ) do
value = frame_args[arg]
if value == nil then
value = frame_args[index];
index = index + 1;
end
new_args[arg] = value;
end
return new_args;
end
--[[
Helper function to handle error messages.
]]
function str._error( error_str )
local frame = mw.getCurrentFrame();
local error_category = frame.args.error_category or 'Страницы с ошибками модуля String';
local ignore_errors = frame.args.ignore_errors or false;
local no_category = frame.args.no_category or false;
if str._getBoolean(ignore_errors) then
return '';
end
local error_str = '<strong class="error">Ошибка модуля String: ' .. error_str .. '</strong>';
if error_category ~= '' and not str._getBoolean( no_category ) then
error_str = '[[Категория:' .. error_category .. ']]' .. error_str;
end
return error_str;
end
--[[
Helper Function to interpret boolean strings
]]
function str._getBoolean( boolean_str )
local boolean_value;
if type( boolean_str ) == 'string' then
boolean_str = boolean_str:lower();
if boolean_str == 'false' or boolean_str == 'no' or boolean_str == '0'
or boolean_str == '' then
boolean_value = false;
else
boolean_value = true;
end
elseif type( boolean_str ) == 'boolean' then
boolean_value = boolean_str;
else
error( 'Логическое значение не найдено' );
end
return boolean_value
end
--[[
Helper function that escapes all pattern characters so that they will be treated
as plain text.
]]
function str._escapePattern( pattern_str )
return mw.ustring.gsub( pattern_str, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" );
end
return str
b4a4e099d7fab23576bae7af327a44c87d13f9cb
Шаблон:Карточка/импортёр/doc
10
258
676
2021-05-18T13:57:26Z
ruwiki>Jaguar K
0
wikitext
text/x-wiki
{{docpage}}
{{Импортёр шаблона-карточки||en|Infobox}}
Этот подстановочный шаблон используется для быстрого перевода параметров карточек из английской Википедии.
Если у вас не получается добиться подстановкой данного шаблона правильного переноса шаблона-карточки из английского раздела, пожалуйста, обратитесь [[Википедия:Форум/Технический|на технический форум]] за помощью в адаптации.
456ee3241716a284eec9a77f6d33a397f9f6181c
Модуль:Hatnote
828
79
130
2021-05-23T00:33:16Z
ruwiki>Grain of sand
0
по [[Обсуждение модуля:Hatnote#navigation-not-searchable|запросу на СО]] от [[u:Lockal|Lockal]]
Scribunto
text/plain
local get_args = require('Module:Arguments').getArgs
local mError
local yesno = function (v) return require('Module:Yesno')(v, true) end
local p, tr = {}, {}
local current_title = mw.title.getCurrentTitle()
local tracking_categories = {
no_prefix = 'Википедия:Страницы с модулем Hatnote без указания префикса',
no_links = 'Википедия:Страницы с модулем Hatnote без ссылок',
red_link = 'Википедия:Страницы с модулем Hatnote с красной ссылкой',
bad_format = 'Википедия:Страницы с модулем Hatnote с некорректно заполненными параметрами',
unparsable_link = 'Википедия:Страницы с модулем Hatnote с нечитаемой ссылкой',
formatted = 'Википедия:Страницы с модулем Hatnote с готовым форматированием',
}
local function index(t1, t2)
return setmetatable(t1, {__index = t2})
end
local function concat(e1, e2)
return tostring(e1) .. tostring(e2)
end
function tr.define_categories(tracked_cases)
local categories = setmetatable({}, {
__tostring = function (self) return table.concat(self) end,
__concat = concat
})
function categories:add(element, nocat)
if not nocat then
local cat_name
if tracked_cases and tracked_cases[element] then
cat_name = tracked_cases[element]
else
cat_name = element
end
table.insert(self, string.format('[[Категория:%s]]', cat_name))
end
end
return categories
end
function tr.error(msg, categories, preview_only)
local current_frame = mw.getCurrentFrame()
local parent_frame = current_frame:getParent()
local res_frame_title = parent_frame and parent_frame:getTitle() ~= current_title.prefixedText and
parent_frame:getTitle() or
current_frame:getTitle()
if not preview_only or current_frame:preprocess('{{REVISIONID}}') == '' then
mError = require('Module:Error')
return mError.error{
tag = 'div',
string.format('Ошибка в [[%s]]: %s.'
.. (preview_only and '<br><small>Это сообщение показывается только во время предпросмотра.</small>' or ''), res_frame_title, msg)
} .. categories
else
return categories
end
end
function p.parse_link(frame)
local args = get_args(frame)
local link = args[1]:gsub('\n', '')
local label
link = mw.text.trim(link:match('^%[%[([^%]]+)%]%]$') or link)
if link:sub(1, 1) == '/' then
label = link
link = current_title.prefixedText .. link
end
link = link:match(':?(.+)')
if link:match('|') then
link, label = link:match('^([^%|]+)%|(.+)$')
end
if not mw.title.new(link) then
return nil, nil
end
return link, label
end
function p.format_link(frame)
-- {{ссылка на раздел}}
local args = get_args(frame)
local link, section, label = args[1], args[2], args[3]
if not link then
link = current_title.prefixedText
if section then
link = '#' .. section
label = label or '§ ' .. section
end
else
local parsed_link, parsed_label = p.parse_link{link}
if parsed_link then
link = parsed_link
else
return link
end
if section and not link:match('#') then
link = link .. '#' .. section
if parsed_label then
parsed_label = parsed_label .. '#' .. section
end
end
label = (label or parsed_label or link):gsub('^([^#]-)#(.+)$', '%1 § %2')
end
if label and label ~= link then
return string.format('[[:%s|%s]]', link, label)
else
return string.format('[[:%s]]', link)
end
end
function p.remove_precision(frame)
-- {{без уточнения}}
local args = get_args(frame)
local title = args[1]
return title:match('^(.+)%s+%b()$') or title
end
function p.is_disambig(frame)
local args = get_args(frame)
local title = args[1]
local page = mw.title.new(title)
if not page or not page.exists or mw.title.equals(page, current_title) then
return false
end
local page_content = page:getContent()
local mw_list_content = mw.title.new('MediaWiki:Disambiguationspage'):getContent()
local lang = mw.language.getContentLanguage()
for template in mw.ustring.gmatch(mw_list_content, '%*%s?%[%[Шаблон:([^%]]+)') do
if page_content:match('{{' .. template) or page_content:match('{{' .. lang:lcfirst(template)) then
return true
end
end
return false
end
function p.list(frame)
local args = get_args(frame, {trim = false})
local list_sep = args.list_sep or args['разделитель списка'] or ', '
local last_list_sep = yesno(args.natural_join) ~= false and ' и ' or list_sep
local links_ns = args.links_ns or args['ПИ ссылок']
local bold_links = yesno(args.bold_links or args['ссылки болдом'])
local res_list = {}
local tracked = {
red_link = false,
bad_format = false,
formatted = false,
unparsable_link = false
}
local i = 1
while args[i] do
local link = args[i]
local label = args['l' .. i]
local element = ''
if link:match('<span') then -- TODO: переписать
tracked.formatted = true
element = link -- for {{не переведено}}
else
local bad_format = (link:match('|') or link:match('[%[%]]')) ~= nil
local parsed_link, parsed_label = p.parse_link{link}
if parsed_link then
tracked.bad_format = tracked.bad_format or bad_format
if links_ns then
parsed_label = parsed_label or parsed_link
parsed_link = mw.site.namespaces[links_ns].name .. ':' .. parsed_link
end
local title = mw.title.new(parsed_link)
tracked.red_link = tracked.red_link or not (title.isExternal or title.exists)
element = p.format_link{parsed_link, nil, label or parsed_label}
else
tracked.unparsable_link = true
element = link
end
end
if bold_links then
element = string.format('<b>%s</b>', element)
end
table.insert(res_list, element)
i = i + 1
end
return setmetatable(res_list, {
__index = tracked,
__tostring = function (self) return mw.text.listToText(self, list_sep, last_list_sep) end,
__concat = concat,
__pairs = function (self) return pairs(tracked) end
})
end
function p.hatnote(frame)
local args = get_args(frame)
local text = args[1]
local id = args.id
local extraclasses = args.extraclasses
local hide_disambig = yesno(args.hide_disambig)
local res = mw.html.create('div')
:attr('id', id)
:addClass('hatnote')
:addClass('navigation-not-searchable')
:addClass(extraclasses)
:wikitext(text)
if hide_disambig then
res:addClass('dabhide')
end
return res
end
function p.main(frame, _tracking_categories)
local args = get_args(frame, {trim = false})
local prefix = args.prefix or args['префикс']
local prefix_plural = args.prefix_plural or args['префикс мн. ч.']
local sep = args.sep or args['разделитель'] or ' '
local dot = yesno(args.dot or args['точка']) and '.' or ''
local nocat = yesno(args.nocat)
local preview_error = yesno(args.preview_error)
local empty_list_message = args.empty_list_message or 'Не указано ни одной страницы'
categories = tr.define_categories(index(_tracking_categories or {}, tracking_categories))
if not prefix then
categories:add('no_prefix', nocat)
return tr.error('Не указан префикс', categories)
end
if not args[1] then
categories:add('no_links', nocat)
return tr.error(empty_list_message, categories, preview_error)
end
if args[2] and prefix_plural then
prefix = prefix_plural
end
local list = p.list(args)
for k, v in pairs(list) do
if type(v) == 'boolean' and v then
categories:add(k, nocat)
end
end
return p.hatnote(index({prefix .. sep .. list .. dot}, args)) .. categories
end
return index(p, tr)
315cdda5f53c2b0188793a6cc6c40f7f371361e0
Модуль:Wikidata/media
828
149
340
2021-07-13T21:52:06Z
ruwiki>Putnik
0
alt=Логотип Викисклада
Scribunto
text/plain
local p = {}
-- Константы
local contentLanguageCode = mw.getContentLanguage():getCode();
function p.formatCommonsCategory( context, options, value )
local link = 'commons:Category:' .. value
local title = value .. ' на Викискладе'
if ( options['text'] and options['text'] ~= '' ) then
title = options['text']
end
commons = '[[' .. link .. '|' .. title .. ']]'
--Commons icon
if ( not options['icon'] or options['icon'] ~= '-' ) then
local icon_size = '15px'
if ( options['icon_size'] and options['icon_size'] ~= '' ) then
icon_size = options['icon_size']
end
commons = '[[File:Commons-logo.svg|' .. icon_size .. '|link=' .. link .. '|alt=Логотип Викисклада]] ' .. commons
end
--Text before and after link
if ( options['text_before'] and options['text_before'] ~= '' ) then
if ( options['text_before'] ~= '-' ) then
commons = options['text_before'] .. ' ' .. commons
end
end
if ( options['text_after'] and options['text_after'] ~= '' ) then
if ( options['text_after'] ~= '-' ) then
commons = commons .. ' ' .. options['text_after']
end
end
return commons
end
--[[
Временный хак, нужно добавить config, getConfig и getCategoryByCode
в options, чтобы они были доступны в любом месте кода.
]]
local config;
local function getCategoryByCode( code, sortkey )
if config == nil then
config = require( 'Module:Wikidata/config' );
end;
local value = config[ 'categories' ][ code ];
if not value or value == '' then
return '';
end
return '[[Category:' .. value .. ']]';
end
local function getCaption( context, options )
local caption = ''
if options.qualifiers and options.qualifiers.P2096 then
for i, qualifier in pairs( options.qualifiers.P2096 ) do
if ( qualifier
and qualifier.datavalue
and qualifier.datavalue.type == 'monolingualtext'
and qualifier.datavalue.value
and qualifier.datavalue.value.language == contentLanguageCode ) then
caption = qualifier.datavalue.value.text
break
end
end
end
if options['appendTimestamp'] and options.qualifiers and options.qualifiers.P585 and options.qualifiers.P585[1] then
local moment = context.formatValueDefault( context, options, options.qualifiers.P585[1].datavalue )
if not caption or caption == '' then
caption = moment
else
caption = caption .. ', ' .. moment
end
end
local localValue = '';
if options[ 'value' ] and options[ 'value' ] ~= '' then
localValue = options[ 'value' ];
end
local localCaption = '';
if options[ 'caption' ] and options[ 'caption' ] ~= '' then
localCaption = options[ 'caption' ];
end
if localValue ~= '' then
caption = localCaption;
end
local formattedCaption = ''
if caption ~= '' then
formattedCaption = context.wrapQualifier( caption, 'P2096', { class = 'media-caption', style = 'display:block' } );
end
if localValue == '' and localCaption ~= '' then
formattedCaption = formattedCaption .. getCategoryByCode( 'media-contains-local-caption' )
if options.frame:preprocess('{{REVISIONID}}') == '' then
formattedCaption = formattedCaption .. '<span class="error" style="font-size:94%;">Локальная подпись не используется, потому что изображение берётся из Викиданных, см. [[Википедия:Шаблоны-карточки#Описание изображения в Викиданных|здесь]]</span>'
end
end
return caption, formattedCaption
end
function p.formatCommonsMediaValue( context, options, value )
local image = value;
local caption, formattedCaption = getCaption( context, options )
if not string.find( value, '[%[%]%{%}]' ) and not string.find( value, 'UNIQ%-%-imagemap' ) then
-- если в value не содержится викикод или imagemap, то викифицируем имя файла
-- ищем слово imagemap в строке, потому что вставляется плейсхолдер: [[PHAB:T28213]]
image = '[[File:' .. value .. '|frameless';
if options[ 'border' ] and options[ 'border' ] ~= '' then
image = image .. '|border';
end
local size = options[ 'size' ];
if size and size ~= '' then
if not string.match( size, 'px$' )
and not string.match( size, 'пкс$' ) -- TODO: использовать перевод для языка вики
then
size = size .. 'px'
end
-- временно
if string.match( size, 'pxpx' ) then
image = '[[Категория:Википедия:Изображение с pxpx в размере]]' .. image
end
else
size = fileDefaultSize;
end
image = image .. '|' .. size;
if options[ 'alt' ] and options[ 'alt' ] ~= '' then
image = image .. '|alt=' .. options[ 'alt' ];
end
if caption ~= '' then
image = image .. '|' .. caption
end
image = image .. ']]';
if formattedCaption ~= '' then
image = image .. '<br>' .. formattedCaption;
end
else
image = image .. formattedCaption .. getCategoryByCode( 'media-contains-markup' );
end
if options.entity and options.fixdouble then
local page = mw.title.getCurrentTitle()
local txt = page:getContent()
if txt and txt:match(':' .. value) and mw.title.getCurrentTitle():inNamespace(0) then
if options.frame:preprocess('{{REVISIONID}}') == '' then
image = image .. '<span class="error">Это изображение встречается ниже по тексту статьи; пожалуйста, уберите одну из копий (не потеряв при этом подпись)</span>'
end
image = image .. getCategoryByCode( 'media-contains-local-double' )
end
end
return image
end
return p
ec384e72491465f4103cce95a8f9467df428a432
Шаблон:Tlinks
10
234
549
2021-07-29T21:07:51Z
ruwiki>WerySkok
0
1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии.
wikitext
text/x-wiki
#перенаправление [[Шаблон:Действия для страницы]]
8d69cbc167e009846a8f6ad7cd75b790882aeff5
Шаблон:Tlp
10
217
643
2021-07-29T21:07:55Z
ruwiki>WerySkok
0
16 версий импортировано: Импорт Инфобокса из Русскоязычной википедии.
wikitext
text/x-wiki
{{{{{|safesubst:}}}#invoke: Template call code | withParams | _link = 1 }}<noinclude>{{doc}}</noinclude>
36c309cb28ccf0901f4fff46cbd35cdabcf00661
Шаблон:Конец скрытого блока
10
199
649
444
2021-07-29T21:08:08Z
ruwiki>WerySkok
0
1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии.
wikitext
text/x-wiki
<includeonly></div></div></includeonly><noinclude>
{{doc|Шаблон:Начало скрытого блока/doc}}</noinclude>
2da6ac8eb0812fb4183a70b516009d40920e281f
Шаблон:Начало скрытого блока
10
196
651
2021-07-29T21:08:09Z
ruwiki>WerySkok
0
1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии.
wikitext
text/x-wiki
<includeonly><!--
--><div class="NavFrame collapsibleBox {{#ifeq: {{{тип|{{{type|}}}}}} | transparent | collapsibleBox-transparent}} {{{состояние|{{{state|collapsed}}}}}}" style="{{#if: {{{Рамка|{{{border|{{{рамка|}}}}}}}}} | border:{{{Рамка|{{{border|{{{рамка}}}}}}}}};}}{{{frame-style|{{{стиль_тела|}}}}}}"><!--
--><div class="NavHead collapsibleBox-title {{#ifeq: {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|}}}}}}}}} | left | collapsibleBox-title-leftTitle | {{#ifeq: {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|}}}}}}}}} | right | collapsibleBox-title-rightTitle}}}} {{#ifeq: {{{Ссылка|{{{ссылка|}}}}}} | left | collapsibleBox-title-leftHideLink | collapsibleBox-title-rightHideLink}}" style="<!--
-->{{#if: {{{Фон_заголовка|{{{bg1|{{{фон_заголовка|}}}}}}}}} | background-color:{{{Фон_заголовка|{{{bg1|{{{фон_заголовка}}}}}}}}};}}<!--
-->{{#if: {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|}}}}}}}}} | text-align:{{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка}}}}}}}}};}}<!--
-->{{#if: {{{Шрифт_заголовка|{{{шрифт_заголовка|}}}}}} | font-weight:{{{Шрифт_заголовка|{{{шрифт_заголовка}}}}}};}}<!--
-->{{#if: {{{Наклон_заголовка|{{{наклон_заголовка|}}}}}} | font-style:{{{Наклон_заголовка|{{{наклон_заголовка}}}}}};}}<!--
-->{{{Стиль_заголовка|{{{extra1|{{{стиль_заголовка|}}}}}}}}}"><!--
-->{{{Заголовок|{{{заголовок|{{{Заглавие|{{{заглавие|{{{Название|{{{название|{{{header|{{{title|{{{1}}}}}}}}}}}}}}}}}}}}}}}}}}}</div><!--
--><div class="NavContent" style="<!--
-->{{#if: {{{Фон_текста|{{{bg2|{{{фон_текста|}}}}}}}}} | background-color:{{{Фон_текста|{{{bg2|{{{фон_текста}}}}}}}}};}}<!--
-->{{#if: {{{Шрифт_текста|{{{шрифт_текста|}}}}}} | font-weight:{{{Шрифт_текста|{{{шрифт_текста}}}}}};}}<!--
-->{{#if: {{{Наклон_текста|{{{наклон_текста|}}}}}} | font-style:{{{Наклон_текста|{{{наклон_текста}}}}}};}}<!--
-->{{#if: {{{Выравнивание_текста|{{{ta2|{{{выравнивание_текста|}}}}}}}}} | text-align:{{{Выравнивание_текста|{{{ta2|{{{выравнивание_текста}}}}}}}}};}}<!--
-->{{{Стиль_текста|{{{extra2|{{{стиль_текста|}}}}}}}}}"><!--
--></includeonly><noinclude>{{doc}}</noinclude>
9de884ce18dcea913832ac31c70e5ddaa0d0d775
Шаблон:Скрытый
10
203
653
452
2021-07-29T21:08:11Z
ruwiki>WerySkok
0
1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии.
wikitext
text/x-wiki
#перенаправление [[Шаблон:Скрытый блок]]
97cc939c1c8ece875b2ec360f85980bd6f1bbed7
Шаблон:Скрытый блок
10
200
655
2021-07-29T21:08:12Z
ruwiki>WerySkok
0
1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии.
wikitext
text/x-wiki
{{Начало скрытого блока
|тип = {{{тип|{{{type|}}}}}}
|состояние = {{{state|{{{состояние|collapsed}}}}}}
|стиль_тела = {{{frame-style|{{{стиль_тела|}}}}}}
|рамка = {{{Рамка|{{{border|{{{рамка|}}}}}}}}}
|заголовок = {{{Заголовок|{{{заголовок|{{{Заглавие|{{{заглавие|{{{Название|{{{название|{{{header|{{{title|{{{1}}}}}}}}}}}}}}}}}}}}}}}}}}}
|ссылка = {{{Ссылка|{{{ссылка|}}}}}}
|шрифт_заголовка = {{{Шрифт_заголовка|{{{шрифт_заголовка|}}}}}}
|наклон_заголовка = {{{Наклон_заголовка|{{{наклон_заголовка|}}}}}}
|фон_заголовка = {{{Фон_заголовка|{{{bg1|{{{фон_заголовка|}}}}}}}}}
|выравнивание_заголовка = {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|}}}}}}}}}
|стиль_заголовка = {{{title-style|{{{Стиль_заголовка|{{{extra1|{{{стиль_заголовка|}}}}}}}}}}}}
|шрифт_текста = {{{Шрифт_текста|{{{шрифт_текста|}}}}}}
|наклон_текста = {{{Наклон_текста|{{{наклон_текста|}}}}}}
|фон_текста = {{{Фон_текста|{{{bg2|{{{фон_текста|}}}}}}}}}
|выравнивание_текста = {{{Выравнивание_текста|{{{ta2|{{{выравнивание_текста|}}}}}}}}}
|стиль_текста = {{{content-style|{{{Стиль_текста|{{{extra2|{{{стиль_текста|}}}}}}}}}}}}}}
{{{content|{{{Содержание|{{{содержание|{{{2}}}}}}}}}}}}
{{#if: {{{footer|}}} | <div style="{{{footer-style|{{{title-style|}}}}}}">{{{footer}}}</div> }}
{{Конец скрытого блока}}<noinclude>{{doc}}</noinclude>
a45c5c78c8132fc840a5e2e10364c35f2cdf5dcc
Модуль:Arguments
828
124
563
290
2021-07-29T21:08:13Z
ruwiki>WerySkok
0
1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии.
Scribunto
text/plain
-- This module provides easy processing of arguments passed to Scribunto from
-- #invoke. It is intended for use by other Lua modules, and should not be
-- called from #invoke directly.
local libraryUtil = require('libraryUtil')
local checkType = libraryUtil.checkType
local arguments = {}
-- Generate four different tidyVal functions, so that we don't have to check the
-- options every time we call it.
local function tidyValDefault(key, val)
if type(val) == 'string' then
val = val:match('^%s*(.-)%s*$')
if val == '' then
return nil
else
return val
end
else
return val
end
end
local function tidyValTrimOnly(key, val)
if type(val) == 'string' then
return val:match('^%s*(.-)%s*$')
else
return val
end
end
local function tidyValRemoveBlanksOnly(key, val)
if type(val) == 'string' then
if val:find('%S') then
return val
else
return nil
end
else
return val
end
end
local function tidyValNoChange(key, val)
return val
end
local function matchesTitle(given, title)
local tp = type( given )
return (tp == 'string' or tp == 'number') and mw.title.new( given ).prefixedText == title
end
local translate_mt = { __index = function(t, k) return k end }
function arguments.getArgs(frame, options)
checkType('getArgs', 1, frame, 'table', true)
checkType('getArgs', 2, options, 'table', true)
frame = frame or {}
options = options or {}
--[[
-- Set up argument translation.
--]]
options.translate = options.translate or {}
if getmetatable(options.translate) == nil then
setmetatable(options.translate, translate_mt)
end
if options.backtranslate == nil then
options.backtranslate = {}
for k,v in pairs(options.translate) do
options.backtranslate[v] = k
end
end
if options.backtranslate and getmetatable(options.backtranslate) == nil then
setmetatable(options.backtranslate, {
__index = function(t, k)
if options.translate[k] ~= k then
return nil
else
return k
end
end
})
end
--[[
-- Get the argument tables. If we were passed a valid frame object, get the
-- frame arguments (fargs) and the parent frame arguments (pargs), depending
-- on the options set and on the parent frame's availability. If we weren't
-- passed a valid frame object, we are being called from another Lua module
-- or from the debug console, so assume that we were passed a table of args
-- directly, and assign it to a new variable (luaArgs).
--]]
local fargs, pargs, luaArgs
if type(frame.args) == 'table' and type(frame.getParent) == 'function' then
if options.wrappers then
--[[
-- The wrappers option makes Module:Arguments look up arguments in
-- either the frame argument table or the parent argument table, but
-- not both. This means that users can use either the #invoke syntax
-- or a wrapper template without the loss of performance associated
-- with looking arguments up in both the frame and the parent frame.
-- Module:Arguments will look up arguments in the parent frame
-- if it finds the parent frame's title in options.wrapper;
-- otherwise it will look up arguments in the frame object passed
-- to getArgs.
--]]
local parent = frame:getParent()
if not parent then
fargs = frame.args
else
local title = parent:getTitle():gsub('/песочница$', '')
local found = false
if matchesTitle(options.wrappers, title) then
found = true
elseif type(options.wrappers) == 'table' then
for _,v in pairs(options.wrappers) do
if matchesTitle(v, title) then
found = true
break
end
end
end
-- We test for false specifically here so that nil (the default) acts like true.
if found or options.frameOnly == false then
pargs = parent.args
end
if not found or options.parentOnly == false then
fargs = frame.args
end
end
else
-- options.wrapper isn't set, so check the other options.
if not options.parentOnly then
fargs = frame.args
end
if not options.frameOnly then
local parent = frame:getParent()
pargs = parent and parent.args or nil
end
end
if options.parentFirst then
fargs, pargs = pargs, fargs
end
else
luaArgs = frame
end
-- Set the order of precedence of the argument tables. If the variables are
-- nil, nothing will be added to the table, which is how we avoid clashes
-- between the frame/parent args and the Lua args.
local argTables = {fargs}
argTables[#argTables + 1] = pargs
argTables[#argTables + 1] = luaArgs
--[[
-- Generate the tidyVal function. If it has been specified by the user, we
-- use that; if not, we choose one of four functions depending on the
-- options chosen. This is so that we don't have to call the options table
-- every time the function is called.
--]]
local tidyVal = options.valueFunc
if tidyVal then
if type(tidyVal) ~= 'function' then
error(
"bad value assigned to option 'valueFunc'"
.. '(function expected, got '
.. type(tidyVal)
.. ')',
2
)
end
elseif options.trim ~= false then
if options.removeBlanks ~= false then
tidyVal = tidyValDefault
else
tidyVal = tidyValTrimOnly
end
else
if options.removeBlanks ~= false then
tidyVal = tidyValRemoveBlanksOnly
else
tidyVal = tidyValNoChange
end
end
--[[
-- Set up the args, metaArgs and nilArgs tables. args will be the one
-- accessed from functions, and metaArgs will hold the actual arguments. Nil
-- arguments are memoized in nilArgs, and the metatable connects all of them
-- together.
--]]
local args, metaArgs, nilArgs, metatable = {}, {}, {}, {}
setmetatable(args, metatable)
local function mergeArgs(tables)
--[[
-- Accepts multiple tables as input and merges their keys and values
-- into one table. If a value is already present it is not overwritten;
-- tables listed earlier have precedence. We are also memoizing nil
-- values, which can be overwritten if they are 's' (soft).
--]]
for _, t in ipairs(tables) do
for key, val in pairs(t) do
if metaArgs[key] == nil and nilArgs[key] ~= 'h' then
local tidiedVal = tidyVal(key, val)
if tidiedVal == nil then
nilArgs[key] = 's'
else
metaArgs[key] = tidiedVal
end
end
end
end
end
--[[
-- Define metatable behaviour. Arguments are memoized in the metaArgs table,
-- and are only fetched from the argument tables once. Fetching arguments
-- from the argument tables is the most resource-intensive step in this
-- module, so we try and avoid it where possible. For this reason, nil
-- arguments are also memoized, in the nilArgs table. Also, we keep a record
-- in the metatable of when pairs and ipairs have been called, so we do not
-- run pairs and ipairs on the argument tables more than once. We also do
-- not run ipairs on fargs and pargs if pairs has already been run, as all
-- the arguments will already have been copied over.
--]]
metatable.__index = function (t, key)
--[[
-- Fetches an argument when the args table is indexed. First we check
-- to see if the value is memoized, and if not we try and fetch it from
-- the argument tables. When we check memoization, we need to check
-- metaArgs before nilArgs, as both can be non-nil at the same time.
-- If the argument is not present in metaArgs, we also check whether
-- pairs has been run yet. If pairs has already been run, we return nil.
-- This is because all the arguments will have already been copied into
-- metaArgs by the mergeArgs function, meaning that any other arguments
-- must be nil.
--]]
if type(key) == 'string' then
key = options.translate[key]
end
local val = metaArgs[key]
if val ~= nil then
return val
elseif metatable.donePairs or nilArgs[key] then
return nil
end
for _, argTable in ipairs(argTables) do
local argTableVal = tidyVal(key, argTable[key])
if argTableVal ~= nil then
metaArgs[key] = argTableVal
return argTableVal
end
end
nilArgs[key] = 'h'
return nil
end
metatable.__newindex = function (t, key, val)
-- This function is called when a module tries to add a new value to the
-- args table, or tries to change an existing value.
if type(key) == 'string' then
key = options.translate[key]
end
if options.readOnly then
error(
'could not write to argument table key "'
.. tostring(key)
.. '"; the table is read-only',
2
)
elseif options.noOverwrite and args[key] ~= nil then
error(
'could not write to argument table key "'
.. tostring(key)
.. '"; overwriting existing arguments is not permitted',
2
)
elseif val == nil then
--[[
-- If the argument is to be overwritten with nil, we need to erase
-- the value in metaArgs, so that __index, __pairs and __ipairs do
-- not use a previous existing value, if present; and we also need
-- to memoize the nil in nilArgs, so that the value isn't looked
-- up in the argument tables if it is accessed again.
--]]
metaArgs[key] = nil
nilArgs[key] = 'h'
else
metaArgs[key] = val
end
end
local function translatenext(invariant)
local k, v = next(invariant.t, invariant.k)
invariant.k = k
if k == nil then
return nil
elseif type(k) ~= 'string' or not options.backtranslate then
return k, v
else
local backtranslate = options.backtranslate[k]
if backtranslate == nil then
-- Skip this one. This is a tail call, so this won't cause stack overflow
return translatenext(invariant)
else
return backtranslate, v
end
end
end
metatable.__pairs = function ()
-- Called when pairs is run on the args table.
if not metatable.donePairs then
mergeArgs(argTables)
metatable.donePairs = true
end
return translatenext, { t = metaArgs }
end
local function inext(t, i)
-- This uses our __index metamethod
local v = t[i + 1]
if v ~= nil then
return i + 1, v
end
end
metatable.__ipairs = function (t)
-- Called when ipairs is run on the args table.
return inext, t, 0
end
return args
end
return arguments
e6be8dfccffa2057c3d50700f350d8d140c1dbf9
Модуль:Calendar
828
62
611
2021-07-29T21:08:14Z
ruwiki>WerySkok
0
1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии.
Scribunto
text/plain
local p = {}
-- Необходимые модули и переменные
local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')
local mwlang = mw.getContentLanguage()
local err = "―" -- NthDay nil result
local tCon = table.concat
-- 00) Блок многократно используемых списков
local bool_to_number={ [true]=1, [false]=0 }
local monthlang = {"января","февраля","марта","апреля","мая","июня","июля","августа","сентября","октября","ноября","декабря"}
local month_to_num = {["января"]=1,["февраля"]=2,["марта"]=3,["апреля"]=4,["мая"]=5,["июня"]=6,
["июля"]=7,["августа"]=8,["сентября"]=9,["октября"]=10,["ноября"]=11,["декабря"]=12,["-"]=""}
local monthd = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
local params = { {"г", "g"}, {"ю", "j"}}
local comment = { '<span style="border-bottom: 1px dotted; cursor: help" title="по юлианскому календарю">','</span>'}
-- duplicates:
-- AST, BST, CST, ECT, IST, MST, PST, SST,
local known_tzs = {
ACDT='+10:30', ACST='+09:30', ACT ='+08:00', ADT ='-03:00', AEDT ='+11:00',
AEST='+10:00', AFT ='+04:30', AKDT='-08:00', AKST ='-09:00', AMST ='+05:00',
AMT ='+04:00', ART ='-03:00', AST ='+03:00', AST ='+04:00', AST ='+03:00',
AST ='-04:00', AWDT='+09:00', AWST='+08:00', AZOST='-01:00', AZT ='+04:00',
BDT ='+08:00', BIOT='+06:00', BIT ='-12:00', BOT ='-04:00', BRT ='-03:00',
BST ='+06:00', BST ='+01:00', BTT ='+06:00', CAT ='+02:00', CCT ='+06:30',
CDT ='-05:00', CEDT='+02:00', CEST='+02:00', CET ='+01:00', CHAST='+12:45',
CIST='-08:00', CKT ='-10:00', CLST='-03:00', CLT ='-04:00', COST ='-04:00',
COT ='-05:00', CST ='-06:00', CST ='+08:00', CVT ='-01:00', CXT ='+07:00',
CHST='+10:00', DFT ='+01:00', EAST='-06:00', EAT ='+03:00', ECT ='-04:00',
ECT ='-05:00', EDT ='-04:00', EEDT='+03:00', EEST ='+03:00', EET ='+02:00',
EST ='-05:00', FJT ='+12:00', FKST='-03:00', FKT ='-04:00', GALT ='-06:00',
GET ='+04:00', GFT ='-03:00', GILT='+12:00', GIT ='-09:00', GMT ='+00:00',
GST ='-02:00', GYT ='-04:00', HADT='-09:00', HAST ='-10:00', HKT ='+08:00',
HMT ='+05:00', HST ='-10:00', IRKT='+08:00', IRST ='+03:30', IST ='+05:30',
IST ='+01:00', IST ='+02:00', JST ='+09:00', KRAT ='+07:00', KST ='+09:00',
LHST='+10:30', LINT='+14:00', MAGT='+11:00', MDT ='-06:00', MIT ='-09:30',
MSD ='+04:00', MSK ='+03:00', MST ='+08:00', MST ='-07:00', MST ='+06:30',
MUT ='+04:00', NDT ='-02:30', NFT ='+11:30', NPT ='+05:45', NST ='-03:30',
NT ='-03:30', OMST='+06:00', PDT ='-07:00', PETT ='+12:00', PHOT ='+13:00',
PKT ='+05:00', PST ='-08:00', PST ='+08:00', RET ='+04:00', SAMT ='+04:00',
SAST='+02:00', SBT ='+11:00', SCT ='+04:00', SLT ='+05:30', SST ='-11:00',
SST ='+08:00', TAHT='-10:00', THA ='+07:00', UTC ='+00:00', UYST ='-02:00',
UYT ='-03:00', VET ='-04:30', VLAT='+10:00', WAT ='+01:00', WEDT ='+01:00',
WEST='+01:00', WET ='+00:00', YAKT='+09:00', YEKT ='+05:00',
-- US Millitary (for RFC-822)
Z='+00:00', A='-01:00', M='-12:00', N='+01:00', Y='+12:00',
}
local category = {
["no_parameters"]=
"<!--[[Категория:Модуль:Calendar:Страницы без параметров]]-->",
["incomplete_parameters"]=
"<!--[[Категория:Модуль:Calendar:Страницы с неполными или некорректными параметрами]]-->",
["without_verification"]=
"<!--[[Категория:Модуль:Calendar:Страницы без проверки параметров]]-->",
["erroneous_parameters"]=
"<!--[[Категория:Модуль:Calendar:Страницы с ошибочными параметрами]]-->"
}
-- несколько параметров передаются вместе с кодом ошибки в таблице, один может быть передан простым значением
local e = {
["start"]="<span class=error>Ошибка: ",
["ending"]=".</span>",
["no_pattern_match"]="строка «%s» не совпадает с заданными паттернами",
["no_valid_date"]="дата «%s» не является корректной",
["wrong_jd"]="юлианская дата %s вне диапазона",
["no_data"]="нет входящих данных",
["too_many_arguments"]="ожидается менее %i аргументов",
["too_little_arguments"]="ожидается более %i аргументов",
["wrong_calculation"]="даты %s и %s не прошли проверку, %s дней разница",
["unknown_param"]="параметр %s неизвестен",
["unknown_error"]="неизвестная ошибка",
["tech_error"]="ошибка в функции %s",
["box_date"]="строка «%s» не является верной датой, пожалуйста, укажите дату в формате ГГГГ-ММ-ДД"
-- [""]="",
}
local tzs_names = {"ACDT","ACST","ACT","ADT","AEDT","AEST","AFT","AKDT","AKST",
"AMST","AMT","ART","AST","AST","AST","AST","AWDT","AWST","AZOST","AZT","BDT",
"BIOT","BIT","BOT","BRT","BST","BST","BTT","CAT","CCT","CDT","CEDT","CEST",
"CET","CHAST","CIST","CKT","CLST","CLT","COST","COT","CST","CST","CVT","CXT",
"CHST","DFT","EAST","EAT","ECT","ECT","EDT","EEDT","EEST","EET","EST","FJT",
"FKST","FKT","GALT","GET","GFT","GILT","GIT","GMT","GST","GYT","HADT","HAST",
"HKT","HMT","HST","IRKT","IRST","IST","IST","IST","JST","KRAT","KST","LHST",
"LINT","MAGT","MDT","MIT","MSD","MSK","MST","MST","MST","MUT","NDT","NFT",
"NPT","NST","NT","OMST","PDT","PETT","PHOT","PKT","PST","PST","RET","SAMT",
"SAST","SBT","SCT","SLT","SST","SST","TAHT","THA","UTC","UYST","UYT","VET",
"VLAT","WAT","WEDT","WEST","WET","YAKT","YEKT","Z","A","M","N","Y","MSK"}
local pattern = { -- для распознавания дат, переданных одним строчным параметром
{"(-?%d%d%d%d?)[-%.%s/\\](%d%d)[-%.%s/\\](%d%d)", ["order"] = {3,2,1} }, -- yyyy mm dd
{"(%d+)[-%.%s/\\](%d+)[-%.%s/\\](%d%d%d%d?)", ["order"] = {1,2,3} }, -- dd mm yyyy
{"(%d%d)[-%.%s/\\](%d%d%d%d?)", ["order"] = {2,3} }, -- mm yyyy
{"(%d%d%d%d?)[-%.%s/\\](%d%d)", ["order"] = {3,2} }, -- yyyy mm
{"(%d+)%s(%l+)%s(%d%d%d%d?)", ["order"] = {1,2,3} }, -- d mmm y
{"(%l+)%s(%d+),?%s(%d%d%d%d?)", ["order"] = {2,1,3} }, -- mmm d, y
{"(%l+)%s(%d%d%d%d?)", ["order"] = {2,3} }, -- mmm y
}
local time_units = {"year","month","day"} --не используется
--[[ local time_units = {"second", "minute", "hour",
"day_of_month", "day_of_week", "day_of_year",
"week", "month", "year", "year_of_century", "century"} ]]--
-- напоминание чтобы сделать более точные пересчёты - с часами / расчёт длительностей периодов
local mnlang = {"ru_G", "ru_N", "en", "de", "fr"}
local month_lang = {
["ru_G"] = {"января","февраля","марта","апреля","мая","июня",
"июля","августа","сентября","октября","ноября","декабря"},
["ru_N"] = {"январь","февраль","март","апрель","май","июнь",
"июль","август","сентябрь","октябрь","ноябрь","декабрь"},
["en"] = {"january", "february", "march", "april", "may", "june",
"july", "august", "september", "october", "november", "december"},
["de"] = {"januar", "februar", "märz", "april", "mai", "juni",
"juli", "august", "september", "oktober", "november", "dezember"},
["fr"] = {"janvier", "février", "mars", "avril", "mai", "juin",
"juillet", "août", "septembre", "octobre", "novembre", "décembre"}
}
-- заполняется автоматически
local reverse_month_lang = {}
-- вспомогательная функция для обращения таблиц (смена ключей со значениями)
local reverse_table = function (strait_table)
local reversed_table = {}
for k,v in pairs(strait_table) do
reversed_table[v] = k
end
return reversed_table
end
-- запуск цикла по заполнению обратных таблиц, необходимых для распознавания дат
local filling_months = function (mnlang, month_lang)
for i=1, #mnlang do
reverse_month_lang[mnlang[i]] = reverse_table(month_lang[mnlang[i]])
end
end
-- 10) Блок общих функций
local function trim(str)
if not str then return nil
else return str:match'^()%s*$' and '' or str:match'^%s*(.*%S)'
end
end
local function purif(str)
if str == "" or str == nil then
return nil
elseif type(tonumber(str)) == "number" then
return math.floor(tonumber(str))
else
return nil
end
-- need .5 -- ,5 number format converter?
end
local function is(str)
if (not str) or (str == "") then return false
else return yesno(str,false)
end
end
local function init(num)
local output = {}
for i=1,num do
table.insert(output, {["year"]="", ["month"]="", ["day"]=""})
end
return unpack(output)
end
local function isyear(tbl)
if type(tbl) ~= 'table' then return false
elseif not tbl["year"] then return false
elseif type(tbl["year"]) == 'number' then return true
else return false
end
end
local function inbord(val, down, up)
return not (type(up) ~= "number" or type(down) ~= "number" or type(val) ~= "number" or up < down or val < down or val > up)
end
local function shallowcopy(orig)
local orig_type = type(orig)
local copy
if orig_type == 'table' then
copy = {}
for orig_key, orig_value in pairs(orig) do
copy[orig_key] = orig_value
end
else -- number, string, boolean, etc
copy = orig
end
return copy
end
local inlist = function ( var, list )
local n = #list
local inlist = false
for i=1,n do
if var == list[i] then inlist = true end
end
return inlist
end
-- 20) Блок общих проверочных функций, связанных с датами
local function unwarp(tbl)
if not tbl then return ""
elseif type(tbl) ~= "table" then return tbl
elseif (tbl.day or tbl.month or tbl.year) then
return (tbl.year or "?").."-"..(tbl.month or "?").."-"..(tbl.day or "?")
else return (tbl[3] or "?").."-"..(tbl[2] or "?").."-"..(tbl[1] or "?")
end
end
local function leap_year(y,jul)
if (not y) or (type(y) ~= "number")
then return false
elseif (y % 4) ~= 0
then return false
elseif not jul and (y % 100 == 0 and y % 400 ~= 0)
then return false
else return true
end
end
-- функция для вычисления последнего дня месяца для юлианского и григорианского календарей
local function month_end_day (month,year,is_julian)
local month_end_day = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} -- если не задан год, дата 29 февраля считается допустимой
if not month or type(month) ~= "number" or month < 1 or month > 12 then return nil
elseif month ~= 2 or not year then return month_end_day[month]
elseif month == 2 and (year % 4) == 0 and not ((not is_julian) and (year % 100 == 0 and year % 400 ~= 0)) then return 29
elseif month == 2 then return 28
else return nil -- в случае не целого значения входящих параметров или при иных непредусмотренных событиях
end
end
local function isdate ( chain , jul ) -- можно использовать для проверки таблиц с полями day, month, year
if not chain then return false
elseif (not type(chain) == "table")
or (not inbord(chain.year,-9999,9999))
or (not inbord(chain.month,1,12))
or (not inbord(chain.day,1,31))
or chain.day > monthd[chain.month]
-- or chain.year == 0
then return false
elseif chain.month == 2 and chain.day == 29 and not leap_year(chain.year,jul)
then return false
else return true end
-- check for other calendars needed?
end
local function ispartdate ( chain )
if not chain then return false
elseif not (type(chain) == "table") then return false
elseif (inbord(chain.year,-9999,9999)
or inbord(chain.month,1,12)
or inbord(chain.day,1,31)) then return true
else return false
end
-- partial date
-- more detailed check for 31.02.0000 needed
-- check for other calendars needed
end
-- from date1 to date2 in one year (beetwen jan-dec, dec-jan needed)
local function partdist(date1,date2)
local mont, dist = 0, 0
local d1d, d1m, d2d, d2m = (date1["day"] or ""), (date1["month"] or ""),(date2["day"] or ""), (date2["month"] or "")
if not (inbord(d1d,1,31) and inbord(d2d,1,31)) then return false end
-- нужна доп. проверка частичных дат на корректность
if (inbord(d1m,1,12) or inbord(d2m,1,12))
and (d1m == "" or d2m == "") then
mont = purif(date1["month"] or date2["month"])
d1m, d2m = mont, mont
end
-- mw.log("📏 day: " ..d1d .."->"..d2d.." month: ".. d1m.."->"..d2m )
if (inbord(d1m,1,12) and d1d <= monthd[d1m])
and (inbord(d2m,1,12) and d2d <= monthd[d2m]) then
if d2m == d1m
then dist = d2d - d1d
else dist = monthd[d1m] - d1d + d2d
end
return dist
else return math.huge
end
end
local function dmdist(d1,d2)
local p1,p2 = math.huge,math.huge
if not not partdist(d1,d2) then
p1=partdist(d1,d2)
end
if not not partdist(d2,d1) then
p1=partdist(d2,d1)
end
-- if (not p1) or (not p2) then
-- return (p1 or "") .. (p2 or "")
-- else
-- mw.log("d1, d2 = " .. undate(d1) .. ", " .. undate(d2))
return math.min(tonumber(partdist(d1,d2)) or math.huge,tonumber(partdist(d2,d1)) or math.huge)
-- end
end
-- 30) Блок функций для обработки ввода-вывода дат
local function undate(tbl)
if not tbl then return ""
else return (tbl.year or "").."-"..(tbl.month or "").."-"..(tbl.day or "")
end
end
-- функция для нормализации значений дат и перевода месяцев в числа
local function numerize(str)
if type(str) == "number" then
return math.floor(str)
elseif str == "" or str == nil or type(str) ~= "string" then
return nil
elseif type(tonumber(str)) == "number" then
return math.floor(tonumber(str))
else
for i=1, #mnlang do
if inlist(mw.ustring.lower(str),month_lang[mnlang[i]]) then
return reverse_month_lang[mnlang[i]][mw.ustring.lower(str)]
end
end
end
end
-- функция распознавания даты, переданной одной строкой
local function parse_date(date_string)
if type(date_string) ~= "string" or date_string == "" then return nil end
local out_date_str = {"","",""}
local error_data = {}
for i=1, #pattern do
local result_1, result_2, result_3 = mw.ustring.match(mw.ustring.lower(date_string),pattern[i][1])
if (result_1 or "") > "" then
out_date_str[pattern[i].order[1]] = result_1
out_date_str[pattern[i].order[2]] = result_2
if (pattern[i].order[3]) then out_date_str[pattern[i].order[3]] = result_3 end
-- mw.log("Паттерн " .. i .. ", строка: " .. date_string)
break
end
end
local date = {
["day"] =numerize(out_date_str[1]),
["month"]=numerize(out_date_str[2]),
["year"] =numerize(out_date_str[3])}
return date --, error_data
end
----[[ УСТАРЕЛО ]]----
local numstr2date = function(numstr)
local format = "Y-m-d"
local iso_date = mwlang:formatDate(format,numstr)
local y,m,d = string.match(iso_date, "(%d+)-(%d+)-(%d+)")
local dateout = {["year"]=purif(y), ["month"]=purif(m), ["day"]=purif(d)}
return dateout
end
--local numstr2date = function(numstr)
-- local nums = {}
-- local dateout = {}
-- for num in string.gmatch(numstr,"(%d+)") do
-- table.insert(nums,purif(num))
-- end
-- if #nums ~= 3 then error("В поле даты вместо трёх чисел с разделителями указано " .. #nums)
-- elseif not inbord(nums[2],1,12) then error("Месяц с номером " .. nums[2] .. " не найден")
-- elseif not inbord(nums[3],1,31) then
-- dateout = {["year"]=nums[3], ["month"]=nums[2], ["day"]=nums[1]}
-- elseif not inbord(nums[1],1,31) then
-- dateout = {["year"]=nums[1], ["month"]=nums[2], ["day"]=nums[3]}
-- elseif inbord(nums[1],1,31) then
-- dateout = {["year"]=nums[3], ["month"]=nums[2], ["day"]=nums[1]}
-- else
-- local mwlang = mw.getContentLanguage()
-- implement mwlang:formatDate(format,datein,true) here
-- return error("Не распознано " .. numstr .. " как дата")
-- end
-- return dateout
--end
local function year2lang(numyear,yearmark,wiki)
if not numyear then return "" end
if not yearmark then yearmark = "" end
local output = ""
local bcmark = " до н. э."
if numyear > 0 then bcmark = ""
else numyear = 1 - numyear end
if wiki then
-- output = tCon({'[[', numyear,' год',bcmark,'|', numyear,']]', " ", yearmark, " ", bcmark})
output = tCon({'[[', numyear,' год',bcmark,'|', trim(numyear .. " " .. yearmark .. " " .. bcmark), ']]'})
else
output = tCon({numyear, " ", yearmark, bcmark})
end
return trim(output)
end
local function day2lang(datein,wikidate,wiki,inner_brt)
-- if not isdate(wikidate) then wiki = false end
if not ispartdate(datein) then return "" end
local dm_separ, output = "", nil
if (not (not datein.day)) and (not (not datein.month)) then dm_separ = " " end
if (not datein.month) then datein.month = "" end
if (not datein.day) then datein.day = "" end
local monlan = monthlang[datein.month] or ""
if wiki and not inner_brt then
output = tCon({"[[", wikidate.day, " ", monthlang[wikidate.month] or "",
"|", (datein.day or ""), dm_separ, monlan, "]]"})
elseif wiki then
output = tCon({"[[", wikidate.day, " ", monthlang[wikidate.month] or "",
"|", (datein.day or ""), dm_separ, monlan})
else
output = tCon({datein.day, dm_separ, monlan})
end
return trim(output)
end
local function triple_txt2date(d,m,y)
-- добавить (args[1]:match("(%a+)") or "-") для нестандартной записи
-- mw.ustring.match((m or ""),"(%a+)")
local msg = ""
local year = purif((y or "-"):match("(%d+)"))
local month = purif(month_to_num[string.lower(mw.ustring.match((m or ""),"(%a+)"))])
local day = purif((d or "-"):match("(%d+)"))
if not month then
msg = category.incomplete_parameters
month = purif(month_to_num[string.lower(mw.ustring.match((d or ""),"(%a+)") or "-")])
end
if (not day) and ((purif(string.match(m or "","(%d+)") or "") or 32) <= (monthd[month] or 31)) then
msg = category.incomplete_parameters
day = purif(m:match("(%d+)") or "")
end
if not year then
msg = category.incomplete_parameters
year = purif(string.match(m or "","(%d+)") or "")
end
local dateout = {["year"]=year, ["month"]=month, ["day"]=day, ["msg"]=msg}
return dateout
end
local function glue(d1,m1,y1,d2,m2,y2)
if (not d1) and (not m1) and (not y1) and (not d2) and (not m2) and (not y2) then
return category.incomplete_parameters end
local gd,gm,gy,jd,jm,jy =
(d1 or ""),
(m1 or ""),
(y1 or ""),
(d2 or ""),
(m2 or ""),
(y2 or "")
--mw.log(tCon({gd,gm,gy,jd,jm,jy}))
local gm_sep = {" [["," год|","]]"}
if (not gy) or (gy == "") then gm_sep = {"","",""} end
return tCon({comment[1],trim(trim(jd .. " " .. jm) .. " " .. jy ),
comment[2]," ([[",trim(gd .. " " .. gm),"]]",gm_sep[1],(gy:match("(%d+)") or ""),
gm_sep[2],gy,gm_sep[3],")",category.incomplete_parameters})
end
-- добавить отображение без года
local function double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark)
local msg = ""
msg = (jdate.msg or "") .. (gdate.msg or "")
local cd = {}
local jd = shallowcopy(jdate)
local gd = shallowcopy(gdate)
local left = "("
local right = ")"
if sq_brts then
left = "["
right = "]"
end
if (not isdate(jdate,true)) then return error((jdate.day or "") .. "." .. (jdate.month or "") .."." .. (jdate.year or "") .. " неподходящая дата")
elseif (not isdate(gdate)) then return error((gdate.day or "") .. "." .. (gdate.month or "") .."." .. (gdate.year or "") .. " неподходящая дата") end
if jd.year == gd.year then
cd.year = gd.year
gd.year, jd.year = nil, nil
end
if jd.month == gd.month then
cd.month = gd.month
gd.month, jd.month = nil, nil
end
if (not not cd.month) and wm then
return tCon({comment[1] .. trim(day2lang(jd,jdate,false) .. " " .. year2lang(jd.year,yearmark,false)) .. comment[2],
trim(left .. day2lang(gd,gdate,wd,wm) .. " " .. year2lang(gd.year,yearmark,wy)) .. right,
day2lang(cd,gdate,false) .. "]]", trim(year2lang(cd.year,yearmark,wy)..msg)}, " ")
end
return tCon({comment[1] .. trim(day2lang(jd,jdate,false) .. " " .. year2lang(jd.year,yearmark,false)) .. comment[2],
trim(left .. day2lang(gd,gdate,wd) .. " " .. year2lang(gd.year,yearmark,wy)) .. right,
trim(day2lang(cd,gdate,false)), trim(year2lang(cd.year,yearmark,wy)..msg)}, " ")
end
-- 40) Блок функций для перевода дат с использованием [[Юлианская дата]]
local function gri2jd( datein )
if not isdate(datein) then return error((datein.day or "") .. "." .. (datein.month or "") .."." .. (datein.year or "") .. " неподходящая дата") end
local year = datein.year
local month = datein.month
local day = datein.day
-- jd calculation
local a = math.floor((14 - month)/12)
local y = year + 4800 - a
local m = month + 12*a - 3
local offset = math.floor(y/4) - math.floor(y/100) + math.floor(y/400) - 32045
local jd = day + math.floor((153*m + 2)/5) + 365*y + offset
-- jd validation
local low, high = -1931076.5, 5373557.49999
if not (low <= jd and jd <= high) then
return error((datein.day or "") .. "." .. (datein.month or "") .. "." .. (datein.year or "") .. " выходит за пределы разрешённого диапазона")
end
return jd
end
local function jd2jul( jd )
if type(jd) ~= "number" then return error("Промежуточная переменная " .. (jd or "") .. " не является числом") end
-- calendar date calculation
local c = jd + 32082
local d = math.floor((4*c + 3)/1461)
local e = c - math.floor(1461*d/4)
local m = math.floor((5*e + 2)/153)
local year_out = d - 4800 + math.floor(m/10)
local month_out = m + 3 - 12*math.floor(m/10)
local day_out = e - math.floor((153*m + 2)/5) + 1
-- output
local dateout = {["year"]=year_out, ["month"]=month_out, ["day"]=day_out}
return dateout
end
local function jul2jd( datein )
if not isdate(datein,true) then return error((datein.day or "") .. "." .. (datein.month or "") ..".".. (datein.year or "") .. " неподходящая дата") end
local year = datein.year
local month = datein.month
local day = datein.day
-- jd calculation
local a = math.floor((14 - month)/12)
local y = year + 4800 - a
local m = month + 12*a - 3
local offset = math.floor(y/4) - 32083
local jd = day + math.floor((153*m + 2)/5) + 365*y + offset
-- jd validation
local low, high = -1930999.5, 5373484.49999
if not (low <= jd and jd <= high) then
return error((datein.day or "") .. "." .. (datein.month or "") .."." .. (datein.year or "") .. " выходит за пределы разрешённого диапазона")
end
return jd
end
local function jd2gri( jd )
if type(jd) ~= "number" then return error("Промежуточная переменная " .. (jd or "") .. " не является числом") end
-- calendar date calculation
local a = jd + 32044
local b = math.floor((4*a + 3) / 146097)
local c = a - math.floor(146097*b/4)
local d = math.floor((4*c+3)/1461)
local e = c - math.floor(1461*d/4)
local m = math.floor((5*e+2)/153)
local day_out = e - math.floor((153*m+2)/5)+1
local month_out = m + 3 - 12*math.floor(m/10)
local year_out = 100*b + d - 4800 + math.floor(m/10)
-- output
local dateout = {["year"]=year_out, ["month"]=month_out, ["day"]=day_out}
return dateout
end
local function astroyear(num, bc)
if not num then return error()
elseif type(num) ~= "number" then return error()
end
if num < 1 then return num end
if not bc then return num
else return 1 - num
end
end
local function recalc(datein,calend)
if inlist(calend,params[1]) then
return jd2jul(gri2jd(datein)), datein
elseif inlist(calend,params[2]) then
return datein, jd2gri(jul2jd(datein))
else error("Параметр " .. (calend or "") .. " не опознан, разрешённые: " .. tCon(params[1]," ") .. " и " .. tCon(params[2]," "))
end
end
-- 50) Функции для обработки UTC
local function utc(str,margin)
local d = 1
local dchar = "+"
local beginning = "[[UTC"
local ending = "]]"
local cat = ""
local nums = {}
local hmarg, timedec = 0, 0
local mmarg = "00"
local output = ""
-- checking type of input
if not margin then margin = 0
elseif type(tonumber(margin)) ~= 'number' then
output = "Can't shift by " .. margin
error(output)
end
if type(str) ~= 'string' then
error("Нет входящей строки")
elseif str:byte(1) == 43 then
elseif inbord(str:byte(1),48,57) then cat = "[[Категория:Википедия:Ошибка в часовом поясе НП]]"
elseif str:byte(1) == 45 or string.sub(str,1,3) == "−" or string.sub(str,1,1)=="-" then d = -1
else
error(string.char(str:byte(1)) .. " недопустимый первый символ")
end
-- parsing input
for num in string.gmatch(str,"(%d+)") do
table.insert(nums,purif(num))
end
if #nums > 2 then error("Ожидается всего 2 числа, а не " .. #nums)
elseif #nums == 0 then error("Необходимо что-то ввести")
elseif #nums == 1 then
if inbord(nums[1],0,14) then timedec = d*nums[1] + margin
else error("Только часы от -14 до 14") end
elseif #nums == 2 then
if not inbord(nums[1],0,14) then error("Только часы от -14 до 14")
elseif not inbord(nums[2],0,59) then error("Минуты только от 0 до 59")
else
timedec = d*(nums[1] + nums[2]/60) + margin
end
end
if tonumber(timedec) == purif(timedec) then hmarg = timedec
else
local h, m = math.modf(math.abs(timedec))
hmarg = h
mmarg = math.floor(m*60)
end
if timedec == 0 then
dchar = "±"
elseif timedec > 0 then
elseif timedec < 0 then
dchar = "−"
end
-- output
output = beginning .. dchar .. math.abs(hmarg) .. ":" .. string.format("%02d",mmarg) .. ending .. cat
return output
end
-- 60) Блок функций ввода-вывода
function p.NthDay( frame )
local args = getArgs(frame, { frameOnly = true })
local num, wday, mont, yea, format =
purif(args[1]), purif(args[2]), purif(args[3]), purif(args[4]), args[5]
if not format then format = "%d.%m.%y" end
if not inbord(num,-5,5) then
return error("The number must be between -5 and 5")
elseif num == 0 then
return error("The number must not be zero") end
if not inbord(wday,0,6) then
return error("The day of the week must be between 0 and 6") end
if not inbord(mont,1,12) then
return error("The month must be between 1 and 12") end
if not inbord(yea,0,9999) then
return error("Wrong year number") end
if inbord(num,1,5) then
local m_start = os.time{year=yea, month=mont, day=1, hour=0}
local m_wds = tonumber(os.date("%w", m_start))
local start_shift = (
(num - bool_to_number[wday >= m_wds]) * 7
- (m_wds - wday)
) * 24 * 60 * 60
local tim = m_start + start_shift
if tonumber(os.date("%m", tim)) == mont then
return (os.date(format, tim))
else
return (err)
end
elseif inbord(num,-5,-1) then
local m_end = os.time{year = yea, month = mont + 1, day = 1, hour = 0} - 24 * 60 * 60
local m_wde = tonumber(os.date("%w", m_end))
local end_shift = ((math.abs(num + 1) + bool_to_number[wday > m_wde]) * 7
+ (m_wde - wday)) * 24 * 60 * 60
local tim = m_end - end_shift
if tonumber(os.date("%m", tim)) == mont then
return (os.date(format, tim))
else
return (err)
end
end
end
-- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"12 декабря 2020"}})
-- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"1.2.1602"}})
-- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"12.12.2021"}})
-- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"2021.12.12"}})
function p.ToIso( frame )
local args = getArgs(frame, { frameOnly = true })
local datein = args[1]
-- инициализация, заполнение обратных таблиц, копирование параметров
filling_months(mnlang, month_lang)
-- парсинг входящей даты по шаблону
local date = parse_date(datein)
if not (type(date.year) == 'number') then
return ("Wrong year: " .. unwarp(date))
end
if not (1 <= date.month and date.month <= 12) then
return ("Wrong month: " .. unwarp(date))
end
if not date.day or not (1 <= date.day and date.day <= month_end_day(date.month,date.year)) then
return ("Wrong day: " .. unwarp(date))
end
local timedate = os.time{year=date.year, month=date.month, day=date.day}
local date = os.date("%Y-%m-%d", timedate)
return date
end
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12 декабря 2020"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"1.2.1602"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"декабрь 2020"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12-2020"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12.12.2021"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"2021.12.12"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"2021.11"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"11.2021"}})
function p.BoxDate( frame )
local args = getArgs(frame, { frameOnly = true })
local txtDateIn, strFormat = args[1], args[2]
local txtDateOut, date, status = p.bxDate(txtDateIn, strFormat, params)
if status.brk then
return error(status.errorText)
else
return txtDateOut
end
end
function p.bxDate( txtDateIn , strFormat, params ) -- к отладке
local txtDateOut, date, status = "", {}, {brk = false, errorCat = "", errorText = ""}
strFormat = strFormat or "j xg Y"
-- заглушка - таблица параметров на будущее
params = params or {}
if not txtDateIn then
status.errorText = e.no_data
status.errorCat = category.no_parameters
status.brk = true
else
-- заполнение служебных таблиц
filling_months(mnlang, month_lang)
end
if not status.brk then
-- парсинг входящей даты по шаблону
date = parse_date(txtDateIn)
-- заменить сообщения об ошибках на списочные
if not (date.year and type(date.year) == 'number') then
status.errorText = string.format(e.box_date,txtDateIn)
status.errorCat = category.incomplete_parameters
status.brk = true
end
if not inbord(date.month,1,12) then
status.errorText = string.format(e.box_date,txtDateIn)
status.errorCat = category.incomplete_parameters
status.brk = true
end
if not date.day and string.find(strFormat,"[dDjlNwzW]") then
strFormat = trim(string.gsub(string.gsub(strFormat,"xg","F"),"[dDjlNwzW]",""))
elseif not date.day then
elseif not inbord(date.day,1,month_end_day(date.month,date.year)) then
status.errorText = string.format(e.box_date,txtDateIn)
status.errorCat = category.incomplete_parameters
status.brk = true
end
end
if not status.brk then
txtDateOut = mwlang:formatDate(strFormat,tCon({date.year,date.month,date.day},"-"),true)
end
return txtDateOut, date, status
end
function p.ToDate( frame ) -- возможно неиспользуемая
local args = getArgs(frame, { frameOnly = true })
local mwlang = mw.getContentLanguage()
local datein = args[1]
local format = "j xg Y"
if not string.match(datein, "%p") then return datein
elseif not args[2] then
else format = args[2]
end
return mwlang:formatDate(format,datein,true)
end
-- =p.unitime(mw.getCurrentFrame():newChild{title="smth",args={"−1:30","1"}})
function p.unitime( frame )
local args = getArgs(frame, { frameOnly = true })
local DST = 0
if not args[2] then
else DST = 1 end
local utcin = ""
local input = args[1]
if not input then return "" end
if inlist(input:upper(),tzs_names) then
utcin = known_tzs[input:upper()]
elseif (string.sub(input:upper(),1,3) == 'UTC') and (string.len(input) < 10) then
utcin = string.sub(input,4)
else
if string.sub(input,1,1) == '['
or string.sub(input,1,1) == '{'
or string.sub(input,1,1):upper() == 'U'
or string.sub(input,1,1):upper() == 'M' then
return input
-- elseif not string.find(string.upper(string.sub(input,1,1)),"[\65-\90]") or
-- not string.find(string.upper(string.sub(input,1,1)),"[\192-\223]") then
-- return input
else utcin = input end
end
-- elseif string.sub(input,1,3) ~= "−" then utcin = input
-- or not (not input:find("[А-я]")) при наличии в строке юникода не работает
local output = ""
if DST == 0 then output = utc(utcin)
else output = utc(utcin) .. ", [[летнее время|летом]] " .. utc(utcin,DST)
end
return output
end
-- УСТАРЕЛО
-- =p.OldDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020","ю",["bc"]="1",["wd"]="1",["wy"]="1",["sq_brts"]="1",["yearmark"]="г."}})
function p.OldDate( frame )
local args = getArgs(frame, { frameOnly = true })
if not args[1] then return err end
local gdate, jdate = {}, {}
local strin = args[1]
local cal = args[2]:lower() or "г"
local bc = is(args["bc"])
local wd = is(args["wd"])
local wm = is(args["wm"])
local wy = is(args["wy"])
if not wd then wm = false end
local sq_brts = is(args["sq_brts"])
local yearmark = "года"
if yesno(args["yearmark"]) then
elseif yesno(args["yearmark"]) == false then yearmark = ""
else yearmark = trim(args["yearmark"]) or "года" end
-- local infocard = is(args["infocard"])
-- local catName = args["catName"] or false
local datein = numstr2date(strin)
datein.year = astroyear(datein.year, bc)
jdate, gdate = recalc(datein,cal)
return double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark)
end
-- =p.NewDate(mw.getCurrentFrame():newChild{title="Salt",args={"2020-02-20"}})
-- =p.NewDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020","ю",["bc"]="1",["wd"]="1",["wy"]="1",["sq_brts"]="1",["yearmark"]="г."}})
-- =p.NewDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020",["bc"]="0",["wd"]="1",["wy"]="1",["sq_brts"]="0",["yearmark"]=""}})
function p.NewDate( frame )
local args = getArgs(frame, { frameOnly = true })
if not args[1] then return err end
local strin = args[1]
local year, month, day
if not not strin:match( "(-?%d%d%d%d%d)-(%d%d)-(%d%d)" ) then
year, month, day = strin:match( "(-?%d%d%d%d%d)-(%d%d)-(%d%d)" )
elseif not not strin:match( "(-?%d+)-(%d+)-(%d+)" ) then
year, month, day = strin:match( "(-?%d+)-(%d+)-(%d+)" )
elseif not not strin:match( "(%d%d)%.(%d%d)%.(-?%d%d%d%d%d)" ) then
day, month, year = strin:match( "(%d%d)%.(%d%d)%.(-?%d%d%d%d%d)" )
elseif not not strin:match( "(%d+)%.(%d+)%.(-?%d+)" ) then
day, month, year = strin:match( "(%d+)%.(%d+)%.(-?%d+)" )
end
if not year then return error(args[1] .. " не подходит под форматы yyyy-mm-dd или dd.mm.yyyy")
end
local cal = "г"
if (not args[2]) or (args[2] == "") then cal = "г"
else cal = args[2]:lower() end
local bc,wd,wm,wy,sq_brts =
is(args["bc"]),
is(args["wd"]),
is(args["wd"]) and is(args["wm"]),
is(args["wy"]),
is(args["sq_brts"])
year = astroyear(purif(year),bc)
local datein = {["year"]=purif(year), ["month"]=purif(month), ["day"]=purif(day)}
local jdate, gdate = recalc(datein,cal)
local yearmark = "года"
local ym = args["yearmark"] or ""
if yesno(ym) then
elseif yesno(ym) == false then yearmark = ""
else
if not not ym:match("(%d+)") then
error("Цифры в обозначении года: " .. ym)
else yearmark = trim(ym) or "года" end
end
return double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark)
end
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"3","июня",nil,"21","мая"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28 августа","","1916 года","15"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"3","июня","1900","21","мая"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"6","июня","1889 год","25","мая"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28","ноября","1917","15"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28 августа","nil","1916 года","15"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"4","января","1915","22","декабря","1914 года"}})
-- {{OldStyleDate|день (НС)|месяц (НС)|год (НС)|день (СС)|месяц (СС)|год (СС)}}
function p.Test( frame )
local args = getArgs(frame, { frameOnly = true })
-- необходима проверка и замена nil на " "
--[[mw.log((args[1] or "") .. " " ..
(args[2] or "") .. " " ..
(args[3] or "") .. " " ..
(args[4] or "") .. " " ..
(args[5] or "") .. " " ..
(args[6] or "")) ]]--
local ingdate = triple_txt2date(args[1],args[2],args[3])
local injdate = triple_txt2date(args[4],args[5],args[6])
local j1date, g1date, j2date, g2date = init(4)
mw.log("ingdate-".. (undate(ingdate) or ""))
mw.log("injdate-".. (undate(injdate) or ""))
local bc,wd,wm,wy,sq_brts,ny =
is(args["bc"]),
is(args["wd"]),
is(args["wd"]) and is(args["wm"]),
is(args["wy"]),
is(args["sq_brts"]),
is(args["ny"])
-- подавление формата для локальных тестов
local wd, wm, wy = true, true, true
local yearmark = "года"
local ym = args["yearmark"] or ((mw.ustring.match((args[3] or ""),"(%a+)") or mw.ustring.match((args[6] or ""),"(%a+)")) or "")
-- mw.log("ym " .. ym)
if yesno(ym) then
elseif yesno(ym) == false then yearmark = ""
else
if not not ym:match("(%d+)") then
error("Цифры в обозначении года: " .. ym)
else yearmark = trim(ym) or "года" end
end
if isdate(ingdate) or isdate(injdate) then
if isdate(ingdate) then
j1date, g1date = recalc(ingdate,"g")
ingdate["full"] = true
end
if isdate(injdate) then
j2date, g2date = recalc(injdate,"j")
injdate["full"] = true
end
if ispartdate(ingdate) and ispartdate(injdate) then
mw.log("📏 " .. dmdist(ingdate,injdate))
mw.log("📏 " .. dmdist(j1date,g1date))
mw.log("📏 " .. dmdist(j2date,g2date))
mw.log("📏 " .. dmdist(ingdate,g1date))
mw.log("📏 " .. dmdist(injdate,j2date))
end
end
if ny then
if isyear(j1date) then
else j1date["year"] = "" end
if isyear(j2date) == nil then
else j2date["year"] = "" end
if isyear(g1date) == nil then
else g1date["year"] = "" end
if isyear(g2date) == nil then
else g2date["year"] = "" end
end
if (isdate(j1date) and isdate(g1date) and isdate(j2date) and isdate(g2date)) then
if ((j1date.year == j2date.year)
and (j1date.month == j2date.month)
and (j1date.day == j2date.day)) then
return double_couple(j1date, g1date, wd, wm, wy, sq_brts, yearmark)
else
mw.log("📏 " .. (tostring(dmdist(ingdate,injdate)) or ""))
return glue(args[1],args[2],args[3],args[4],args[5],args[6])
-- категория (предположительная разница в днях) и частичный вывод
end
elseif isdate(j1date) and isdate(g1date) then
return double_couple(j1date, g1date, wd, wm, wy, sq_brts, yearmark) -- категория плюс частичная проверка
elseif isdate(j2date) and isdate(g2date) then
return double_couple(j2date, g2date, wd, wm, wy, sq_brts, yearmark) -- категория плюс частичная проверка
elseif (ispartdate(ingdate) and ispartdate(injdate)) then
mw.log("ingdate ".. (undate(ingdate) or ""))
mw.log("injdate ".. (undate(injdate) or ""))
mw.log("j1date " .. (undate(j1date ) or ""))
mw.log("j2date " .. (undate(j2date ) or ""))
mw.log("g1date " .. (undate(g1date ) or ""))
mw.log("g2date " .. (undate(g2date ) or ""))
mw.log("📏 " .. (tostring(partdist(ingdate,injdate)) or "").. " — " .. (tostring(partdist(injdate,ingdate)) or ""))
return glue(args[1],args[2],args[3],args[4],args[5],args[6])
-- частичный или полный вывод, категория
else
mw.log("ingdate ".. (undate(ingdate) or ""))
mw.log("injdate ".. (undate(injdate) or ""))
mw.log("j1date " .. (undate(j1date ) or ""))
mw.log("j2date " .. (undate(j2date ) or ""))
mw.log("g1date " .. (undate(g1date ) or ""))
mw.log("g2date " .. (undate(g2date ) or ""))
return err .. category.incomplete_parameters
end
end
return p
6b74a9b40b904aa7b7b9e465d1b64613451b5b94
Модуль:Category handler
828
31
613
414
2021-07-29T21:08:14Z
ruwiki>WerySkok
0
1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии.
Scribunto
text/plain
--------------------------------------------------------------------------------
-- --
-- CATEGORY HANDLER --
-- --
-- This module implements the {{category handler}} template in Lua, --
-- with a few improvements: all namespaces and all namespace aliases --
-- are supported, and namespace names are detected automatically for --
-- the local wiki. This module requires [[Module:Namespace detect]] --
-- and [[Module:Yesno]] to be available on the local wiki. It can be --
-- configured for different wikis by altering the values in --
-- [[Module:Category handler/config]], and pages can be blacklisted --
-- from categorisation by using [[Module:Category handler/blacklist]]. --
-- --
--------------------------------------------------------------------------------
-- Load required modules
local yesno = require('Module:Yesno')
-- Lazily load things we don't always need
local mShared, mappings
local p = {}
--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------
local function trimWhitespace(s, removeBlanks)
if type(s) ~= 'string' then
return s
end
s = s:match('^%s*(.-)%s*$')
if removeBlanks then
if s ~= '' then
return s
else
return nil
end
else
return s
end
end
--------------------------------------------------------------------------------
-- CategoryHandler class
--------------------------------------------------------------------------------
local CategoryHandler = {}
CategoryHandler.__index = CategoryHandler
function CategoryHandler.new(data, args)
local obj = setmetatable({ _data = data, _args = args }, CategoryHandler)
-- Set the title object
do
local pagename = obj:parameter('demopage')
local success, titleObj
if pagename then
success, titleObj = pcall(mw.title.new, pagename)
end
if success and titleObj then
obj.title = titleObj
if titleObj == mw.title.getCurrentTitle() then
obj._usesCurrentTitle = true
end
else
obj.title = mw.title.getCurrentTitle()
obj._usesCurrentTitle = true
end
end
-- Set suppression parameter values
for _, key in ipairs{'nocat', 'categories'} do
local value = obj:parameter(key)
value = trimWhitespace(value, true)
obj['_' .. key] = yesno(value)
end
do
local subpage = obj:parameter('subpage')
local category2 = obj:parameter('category2')
if type(subpage) == 'string' then
subpage = mw.ustring.lower(subpage)
end
if type(category2) == 'string' then
subpage = mw.ustring.lower(category2)
end
obj._subpage = trimWhitespace(subpage, true)
obj._category2 = trimWhitespace(category2) -- don't remove blank values
end
return obj
end
function CategoryHandler:parameter(key)
local parameterNames = self._data.parameters[key]
local pntype = type(parameterNames)
if pntype == 'string' or pntype == 'number' then
return self._args[parameterNames]
elseif pntype == 'table' then
for _, name in ipairs(parameterNames) do
local value = self._args[name]
if value ~= nil then
return value
end
end
return nil
else
error(string.format(
'invalid config key "%s"',
tostring(key)
), 2)
end
end
function CategoryHandler:isSuppressedByArguments()
return
-- See if a category suppression argument has been set.
self._nocat == true
or self._categories == false
or (
self._category2
and self._category2 ~= self._data.category2Yes
and self._category2 ~= self._data.category2Negative
)
-- Check whether we are on a subpage, and see if categories are
-- suppressed based on our subpage status.
or self._subpage == self._data.subpageNo and self.title.isSubpage
or self._subpage == self._data.subpageOnly and not self.title.isSubpage
end
function CategoryHandler:shouldSkipBlacklistCheck()
-- Check whether the category suppression arguments indicate we
-- should skip the blacklist check.
return self._nocat == false
or self._categories == true
or self._category2 == self._data.category2Yes
end
function CategoryHandler:matchesBlacklist()
if self._usesCurrentTitle then
return self._data.currentTitleMatchesBlacklist
else
mShared = mShared or require('Module:Category handler/shared')
return mShared.matchesBlacklist(
self.title.prefixedText,
mw.loadData('Module:Category handler/blacklist')
)
end
end
function CategoryHandler:isSuppressed()
-- Find if categories are suppressed by either the arguments or by
-- matching the blacklist.
return self:isSuppressedByArguments()
or not self:shouldSkipBlacklistCheck() and self:matchesBlacklist()
end
function CategoryHandler:getNamespaceParameters()
if self._usesCurrentTitle then
return self._data.currentTitleNamespaceParameters
else
if not mappings then
mShared = mShared or require('Module:Category handler/shared')
mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData
end
return mShared.getNamespaceParameters(
self.title,
mappings
)
end
end
function CategoryHandler:namespaceParametersExist()
-- Find whether any namespace parameters have been specified.
-- We use the order "all" --> namespace params --> "other" as this is what
-- the old template did.
if self:parameter('all') then
return true
end
if not mappings then
mShared = mShared or require('Module:Category handler/shared')
mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData
end
for ns, params in pairs(mappings) do
for i, param in ipairs(params) do
if self._args[param] then
return true
end
end
end
if self:parameter('other') then
return true
end
return false
end
function CategoryHandler:getCategories()
local params = self:getNamespaceParameters()
local nsCategory
for i, param in ipairs(params) do
local value = self._args[param]
if value ~= nil then
nsCategory = value
break
end
end
if nsCategory ~= nil or self:namespaceParametersExist() then
-- Namespace parameters exist - advanced usage.
if nsCategory == nil then
nsCategory = self:parameter('other')
end
local ret = {self:parameter('all')}
local numParam = tonumber(nsCategory)
if numParam and numParam >= 1 and math.floor(numParam) == numParam then
-- nsCategory is an integer
ret[#ret + 1] = self._args[numParam]
else
ret[#ret + 1] = nsCategory
end
if #ret < 1 then
return nil
else
return table.concat(ret)
end
elseif self._data.defaultNamespaces[self.title.namespace] then
-- Namespace parameters don't exist, simple usage.
return self._args[1]
end
return nil
end
--------------------------------------------------------------------------------
-- Exports
--------------------------------------------------------------------------------
local p = {}
function p._exportClasses()
-- Used for testing purposes.
return {
CategoryHandler = CategoryHandler
}
end
function p._main(args, data)
data = data or mw.loadData('Module:Category handler/data')
local handler = CategoryHandler.new(data, args)
if handler:isSuppressed() then
return nil
end
return handler:getCategories()
end
function p.main(frame, data)
data = data or mw.loadData('Module:Category handler/data')
local args = require('Module:Arguments').getArgs(frame, {
wrappers = data.wrappers,
valueFunc = function (k, v)
v = trimWhitespace(v)
if type(k) == 'number' then
if v ~= '' then
return v
else
return nil
end
else
return v
end
end
})
return p._main(args, data)
end
return p
b74dd63857b24904ac452429b11213f18647471f
Модуль:Category handler/blacklist
828
75
615
122
2021-07-29T21:08:14Z
ruwiki>WerySkok
0
1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии.
Scribunto
text/plain
-- This module contains the blacklist used by [[Module:Category handler]].
-- Pages that match Lua patterns in this list will not be categorised unless
-- categorisation is explicitly requested.
return {
'^Main Page$', -- don't categorise the main page.
-- Don't categorise the following pages or their subpages.
-- "%f[/\0]" matches if the next character is "/" or the end of the string.
'^Wikipedia:Cascade%-protected items%f[/\0]',
'^User:UBX%f[/\0]', -- The userbox "template" space.
'^User talk:UBX%f[/\0]',
-- Don't categorise subpages of these pages, but allow
-- categorisation of the base page.
'^Wikipedia:Template messages/.*$',
'/[aA]rchive' -- Don't categorise archives.
}
c84948ad9808d5d323408d5d10d5652f748a0550
Модуль:Category handler/config
828
70
617
112
2021-07-29T21:08:15Z
ruwiki>WerySkok
0
1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии.
Scribunto
text/plain
--------------------------------------------------------------------------------
-- [[Module:Category handler]] configuration data --
-- Language-specific parameter names and values can be set here. --
-- For blacklist config, see [[Module:Category handler/blacklist]]. --
--------------------------------------------------------------------------------
local cfg = {} -- Don't edit this line.
--------------------------------------------------------------------------------
-- Start configuration data --
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Parameter names --
-- These configuration items specify custom parameter names. --
-- To add one extra name, you can use this format: --
-- --
-- foo = 'parameter name', --
-- --
-- To add multiple names, you can use this format: --
-- --
-- foo = {'parameter name 1', 'parameter name 2', 'parameter name 3'}, --
--------------------------------------------------------------------------------
cfg.parameters = {
-- The nocat and categories parameter suppress
-- categorisation. They are used with Module:Yesno, and work as follows:
--
-- cfg.nocat:
-- Result of yesno() Effect
-- true Categorisation is suppressed
-- false Categorisation is allowed, and
-- the blacklist check is skipped
-- nil Categorisation is allowed
--
-- cfg.categories:
-- Result of yesno() Effect
-- true Categorisation is allowed, and
-- the blacklist check is skipped
-- false Categorisation is suppressed
-- nil Categorisation is allowed
nocat = 'nocat',
categories = 'categories',
-- The parameter name for the legacy "category2" parameter. This skips the
-- blacklist if set to the cfg.category2Yes value, and suppresses
-- categorisation if present but equal to anything other than
-- cfg.category2Yes or cfg.category2Negative.
category2 = 'category2',
-- cfg.subpage is the parameter name to specify how to behave on subpages.
subpage = 'subpage',
-- The parameter for data to return in all namespaces.
all = 'all',
-- The parameter name for data to return if no data is specified for the
-- namespace that is detected.
other = 'other',
-- The parameter name used to specify a page other than the current page;
-- used for testing and demonstration.
demopage = 'page',
}
--------------------------------------------------------------------------------
-- Parameter values --
-- These are set values that can be used with certain parameters. Only one --
-- value can be specified, like this: --
-- --
-- cfg.foo = 'value name' -- --
--------------------------------------------------------------------------------
-- The following settings are used with the cfg.category2 parameter. Setting
-- cfg.category2 to cfg.category2Yes skips the blacklist, and if cfg.category2
-- is present but equal to anything other than cfg.category2Yes or
-- cfg.category2Negative then it supresses cateogrisation.
cfg.category2Yes = 'yes'
cfg.category2Negative = '¬'
-- The following settings are used with the cfg.subpage parameter.
-- cfg.subpageNo is the value to specify to not categorise on subpages;
-- cfg.subpageOnly is the value to specify to only categorise on subpages.
cfg.subpageNo = 'no'
cfg.subpageOnly = 'only'
--------------------------------------------------------------------------------
-- Default namespaces --
-- This is a table of namespaces to categorise by default. The keys are the --
-- namespace numbers. --
--------------------------------------------------------------------------------
cfg.defaultNamespaces = {
[ 0] = true, -- main
[ 6] = true, -- file
[ 12] = true, -- help
[ 14] = true, -- category
[100] = true, -- portal
[108] = true, -- book
}
--------------------------------------------------------------------------------
-- Wrappers --
-- This is a wrapper template or a list of wrapper templates to be passed to --
-- [[Module:Arguments]]. --
--------------------------------------------------------------------------------
cfg.wrappers = 'Template:Category handler'
--------------------------------------------------------------------------------
-- End configuration data --
--------------------------------------------------------------------------------
return cfg -- Don't edit this line.
373cd107b13a5b00e6a1b7e66a749f12502c849d
Модуль:Category handler/data
828
69
619
110
2021-07-29T21:08:15Z
ruwiki>WerySkok
0
1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии.
Scribunto
text/plain
-- This module assembles data to be passed to [[Module:Category handler]] using
-- mw.loadData. This includes the configuration data and whether the current
-- page matches the title blacklist.
local data = require('Module:Category handler/config')
local mShared = require('Module:Category handler/shared')
local blacklist = require('Module:Category handler/blacklist')
local title = mw.title.getCurrentTitle()
data.currentTitleMatchesBlacklist = mShared.matchesBlacklist(
title.prefixedText,
blacklist
)
data.currentTitleNamespaceParameters = mShared.getNamespaceParameters(
title,
mShared.getParamMappings()
)
return data
abbc68048ff698e88dda06b64ecf384bbf583120
Модуль:Category handler/shared
828
74
621
120
2021-07-29T21:08:15Z
ruwiki>WerySkok
0
1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии.
Scribunto
text/plain
-- This module contains shared functions used by [[Module:Category handler]]
-- and its submodules.
local p = {}
function p.matchesBlacklist(page, blacklist)
for i, pattern in ipairs(blacklist) do
local match = mw.ustring.match(page, pattern)
if match then
return true
end
end
return false
end
function p.getParamMappings(useLoadData)
local dataPage = 'Module:Namespace detect/data'
if useLoadData then
return mw.loadData(dataPage).mappings
else
return require(dataPage).mappings
end
end
function p.getNamespaceParameters(titleObj, mappings)
-- We don't use title.nsText for the namespace name because it adds
-- underscores.
local mappingsKey
if titleObj.isTalkPage then
mappingsKey = 'talk'
else
mappingsKey = mw.site.namespaces[titleObj.namespace].name
end
mappingsKey = mw.ustring.lower(mappingsKey)
return mappings[mappingsKey] or {}
end
return p
d2d5de1a031e6ce97c242cbfa8afe7a92cb9eca5
Модуль:Message box
828
21
623
2021-07-29T21:08:16Z
ruwiki>WerySkok
0
1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии.
Scribunto
text/plain
-- This is a meta-module for producing message box templates, including
-- {{mbox}}, {{ambox}}, {{imbox}}, {{tmbox}}, {{ombox}}, {{cmbox}} and {{fmbox}}.
-- Load necessary modules.
require('Module:No globals')
local getArgs
local categoryHandler = require('Module:Category handler')._main
local yesno = require('Module:Yesno')
local boxDate = require('Module:Calendar').bxDate;
-- Get a language object for formatDate and ucfirst.
local lang = mw.language.getContentLanguage()
-- Define constants
local CONFIG_MODULE = 'Module:Message box/configuration'
--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------
local function getTitleObject(...)
-- Get the title object, passing the function through pcall
-- in case we are over the expensive function count limit.
local success, title = pcall(mw.title.new, ...)
if success then
return title
end
end
local function union(t1, t2)
-- Returns the union of two arrays.
local vals = {}
for i, v in ipairs(t1) do
vals[v] = true
end
for i, v in ipairs(t2) do
vals[v] = true
end
local ret = {}
for k in pairs(vals) do
table.insert(ret, k)
end
table.sort(ret)
return ret
end
local function getArgNums(args, prefix)
local nums = {}
for k, v in pairs(args) do
local num = mw.ustring.match(tostring(k), '^' .. prefix .. '([1-9]%d*)$')
if num then
table.insert(nums, tonumber(num))
end
end
table.sort(nums)
return nums
end
-- локальная обёртка, игнорирует таблицу с номерами дня, месяца и года
local function formatDate(txtDateIn, strFormat, params)
local txtDateOut, date, status = boxDate(txtDateIn, strFormat, params)
if status.brk then
return error(status.errorText)
else
return txtDateOut
end
end
--------------------------------------------------------------------------------
-- Box class definition
--------------------------------------------------------------------------------
local MessageBox = {}
MessageBox.__index = MessageBox
function MessageBox.new(boxType, args, cfg)
args = args or {}
local obj = {}
-- Set the title object and the namespace.
obj.title = getTitleObject(args.page) or mw.title.getCurrentTitle()
-- Set the config for our box type.
obj.cfg = cfg[boxType]
if not obj.cfg then
local ns = obj.title.namespace
-- boxType is "mbox" or invalid input
if ns == 0 then
obj.cfg = cfg.ambox -- main namespace
elseif ns == 6 then
obj.cfg = cfg.imbox -- file namespace
elseif ns == 14 then
obj.cfg = cfg.cmbox -- category namespace
else
local nsTable = mw.site.namespaces[ns]
if nsTable and nsTable.isTalk then
obj.cfg = cfg.tmbox -- any talk namespace
else
obj.cfg = cfg.ombox -- other namespaces or invalid input
end
end
end
-- Set the arguments, and remove all blank arguments except for the ones
-- listed in cfg.allowBlankParams.
do
local newArgs = {}
for k, v in pairs(args) do
if v ~= '' then
newArgs[k] = v
end
end
for i, param in ipairs(obj.cfg.allowBlankParams or {}) do
newArgs[param] = args[param]
end
obj.args = newArgs
end
-- Define internal data structure.
obj.categories = {}
obj.classes = {}
return setmetatable(obj, MessageBox)
end
function MessageBox:addCat(ns, cat, sort)
if not cat then
return nil
end
if sort then
cat = string.format('[[Категория:%s|%s]]', cat, sort)
else
cat = string.format('[[Категория:%s]]', cat)
end
self.categories[ns] = self.categories[ns] or {}
table.insert(self.categories[ns], cat)
end
function MessageBox:addClass(class)
if not class then
return nil
end
table.insert(self.classes, class)
end
function MessageBox:setParameters()
local args = self.args
local cfg = self.cfg
-- Get type data.
self.type = args.type
local typeData = cfg.types[self.type]
self.invalidTypeError = cfg.showInvalidTypeError
and self.type
and not typeData
typeData = typeData or cfg.types[cfg.default]
self.typeClass = typeData.class
self.typeImage = typeData.image
-- Find if the box has been wrongly substituted.
self.isSubstituted = cfg.substCheck and args.subst == 'SUBST'
-- Find whether we are using a small message box.
self.isSmall = cfg.allowSmall and (
cfg.smallParam and args.small == cfg.smallParam
or not cfg.smallParam and yesno(args.small)
)
-- Add attributes, classes and styles.
self.id = args.id
if yesno(args.plainlinks) ~= false then
self:addClass('plainlinks')
end
if args.mini then
self:addClass('ambox-mini')
end
for _, class in ipairs(cfg.classes or {}) do
self:addClass(class)
end
if self.isSmall then
self:addClass(cfg.smallClass or 'mbox-small')
end
self:addClass(self.typeClass)
self:addClass(args.class)
self.style = args.style
self.attrs = args.attrs
self.dataLabel1 = args['data-label-1']
self.dataLabel2 = args['data-label-2']
self.dataLabel3 = args['data-label-3']
self.dataValue1 = args['data-value-1']
self.dataValue2 = args['data-value-2']
self.dataValue3 = args['data-value-3']
-- Set text style.
self.textstyle = args.textstyle
-- Find if we are on the template page or not. This functionality is only
-- used if useCollapsibleTextFields is set, or if both cfg.templateCategory
-- and cfg.templateCategoryRequireName are set.
self.useCollapsibleTextFields = cfg.useCollapsibleTextFields
if self.useCollapsibleTextFields
or cfg.templateCategory
and cfg.templateCategoryRequireName
then
self.name = args.name
if self.name then
local templateName = mw.ustring.match(
self.name,
'^[tT][eE][mM][pP][lL][aA][tT][eE][%s_]*:[%s_]*(.*)$'
) or self.name
templateName = ('Template:' .. templateName) or ('Шаблон:' .. templateName)
self.templateTitle = getTitleObject(templateName)
end
self.isTemplatePage = self.templateTitle
and mw.title.equals(self.title, self.templateTitle)
end
-- Process data for collapsible text fields. At the moment these are only
-- used in {{ambox}}.
if self.useCollapsibleTextFields then
-- Get the self.issue value.
if self.isSmall and args.smalltext then
self.issue = args.smalltext
else
local sect
if args.sect == '' then
sect = '<span style="font-weight:bold">Эта ' .. (cfg.sectionDefault or 'статья') .. '</span>'
elseif type(args.sect) == 'string' then
sect = '<span style="font-weight:bold">' .. args.sect .. '</span>'
end
local issue = args.issue
issue = type(issue) == 'string' and issue ~= '' and issue or nil
local text = args.text
text = type(text) == 'string' and text or nil
local issues = {}
table.insert(issues, sect)
table.insert(issues, issue)
table.insert(issues, text)
self.issue = table.concat(issues, ' ')
end
-- Get the self.talk value.
local talk = args.talk
-- Show talk links on the template page or template subpages if the talk
-- parameter is blank.
if talk == ''
and self.templateTitle
and (
mw.title.equals(self.templateTitle, self.title)
or self.title:isSubpageOf(self.templateTitle)
)
then
talk = '#'
elseif talk == '' then
talk = nil
end
if talk then
-- If the talk value is a talk page, make a link to that page. Else
-- assume that it's a section heading, and make a link to the talk
-- page of the current page with that section heading.
local talkTitle = getTitleObject(talk)
local talkArgIsTalkPage = true
if not talkTitle or not talkTitle.isTalkPage then
talkArgIsTalkPage = false
talkTitle = getTitleObject(
self.title.text,
mw.site.namespaces[self.title.namespace].talk.id
)
end
if talkTitle and talkTitle.exists then
local talkText = 'Соответствующую дискуссию можно найти на'
if talkArgIsTalkPage then
talkText = string.format(
'%s [[%s|%s]].',
talkText,
talk,
talkTitle.prefixedText
)
else
talkText = string.format(
'%s [[%s#%s|странице обсуждения]].',
talkText,
talkTitle.prefixedText,
talk
)
end
self.talk = talkText
end
end
-- Get other values.
self.fix = args.fix ~= '' and args.fix or nil
local date
if args.date and args.date ~= '' then
local status, result = pcall(formatDate, args.date)
if status then
date = string.format("(<span class='date'>%s</span>)", result)
else
date = string.format("<span class='error'>(Строка «%s» не является верной датой, пожалуйста, укажите дату в формате <code>ГГГГ-ММ-ДД</code>)</span>", args.date)
end
elseif args.date == '' and self.isTemplatePage then
date = string.format("(<span class='date'>%s</span>)", formatDate( lang:formatDate('Y-m-d') ) ) -- тут возникновения ошибки, связанной с пользовательским вводом, не будет
end
if date then
self.date = string.format(" <span class='mbox-date'>''%s''</span>", date)
end
self.info = args.info
if yesno(args.removalnotice) then
self.removalNotice = cfg.removalNotice
end
if args.shortFix then
self.shortFix = args.shortFix
end
end
-- Set the non-collapsible text field. At the moment this is used by all box
-- types other than ambox, and also by ambox when small=yes.
if self.isSmall then
self.text = args.smalltext or args.text
else
self.text = args.text
self.textsmall = args['text-small']
end
-- Set the below row.
self.below = cfg.below and args.below
-- General image settings.
self.imageCellDiv = not self.isSmall and cfg.imageCellDiv
self.imageEmptyCell = cfg.imageEmptyCell
if cfg.imageEmptyCellStyle then
self.imageEmptyCellStyle = 'border:none;padding:0px;width:1px'
end
-- Left image settings.
local imageLeft = self.isSmall and args.smallimage or args.image
if cfg.imageCheckBlank and imageLeft ~= 'blank' and imageLeft ~= 'none' and imageLeft ~= ''
or not cfg.imageCheckBlank and imageLeft ~= 'none'
then
self.imageLeft = imageLeft
if not imageLeft then
local imageSize = self.isSmall
and (cfg.imageSmallSize or '30x30px')
or cfg.imageSize
or '40x40px'
self.imageLeft = string.format('[[File:%s|%s|alt=]]', self.typeImage
or 'Information icon4.svg', imageSize)
end
end
-- Right image settings.
local imageRight = self.isSmall and args.smallimageright or args.imageright
if not (cfg.imageRightNone and imageRight == 'none') then
self.imageRight = imageRight
end
end
function MessageBox:setMainspaceCategories()
local args = self.args
local cfg = self.cfg
local date = nil
if not cfg.allowMainspaceCategories then
return nil
end
local nums = {}
for _, prefix in ipairs{'cat', 'category', 'all'} do
args[prefix .. '1'] = args[prefix]
nums = union(nums, getArgNums(args, prefix))
end
-- The following is roughly equivalent to the old {{Ambox/category}}.
local status, result = pcall(formatDate, args.date, 'xg Y')
if status then
date = result
end
date = type(date) == 'string' and date
local preposition = 'с'
local suffix = 'года'
for _, num in ipairs(nums) do
local mainCat = args['cat' .. tostring(num)]
or args['category' .. tostring(num)]
local allCat = args['all' .. tostring(num)]
mainCat = type(mainCat) == 'string' and mainCat
allCat = type(allCat) == 'string' and allCat
if mainCat and date and date ~= '' then
local catTitle = string.format('%s %s %s %s', mainCat, preposition, date, suffix)
self:addCat(0, catTitle)
catTitle = getTitleObject('Категория:' .. catTitle)
local status, result = pcall(formatDate, args.date)
if not status then
self:addCat(0, 'Википедия:Статьи с недопустимым параметром даты в шаблоне-сообщении')
end
elseif mainCat and (not date or date == '') then
self:addCat(0, mainCat)
end
if allCat then
self:addCat(0, allCat)
end
end
end
function MessageBox:setTemplateCategories()
local args = self.args
local cfg = self.cfg
-- Add template categories.
if cfg.templateCategory then
if cfg.templateCategoryRequireName then
if self.isTemplatePage then
self:addCat(10, cfg.templateCategory)
end
elseif not self.title.isSubpage then
self:addCat(10, cfg.templateCategory)
end
end
-- Add template error categories.
if cfg.templateErrorCategory then
local templateErrorCategory = cfg.templateErrorCategory
local templateCat, templateSort
if not self.name and not self.title.isSubpage then
templateCat = templateErrorCategory
elseif self.isTemplatePage then
local paramsToCheck = cfg.templateErrorParamsToCheck or {}
local count = 0
for i, param in ipairs(paramsToCheck) do
if not args[param] then
count = count + 1
end
end
if count > 0 then
templateCat = templateErrorCategory
templateSort = tostring(count)
end
if self.categoryNums and #self.categoryNums > 0 then
templateCat = templateErrorCategory
templateSort = 'C'
end
end
self:addCat(10, templateCat, templateSort)
end
end
function MessageBox:setAllNamespaceCategories()
-- Set categories for all namespaces.
if self.invalidTypeError then
local allSort = (self.title.namespace == 0 and 'Main:' or '') .. self.title.prefixedText
self:addCat('all', 'Википедия:Необходимо исправить параметр в шаблоне-сообщении', allSort)
end
if self.isSubstituted then
self:addCat('all', 'Википедия:Страницы с ошибочно подставленными шаблонами')
end
end
function MessageBox:setCategories()
if self.title.namespace == 0 then
self:setMainspaceCategories()
elseif self.title.namespace == 10 then
self:setTemplateCategories()
end
self:setAllNamespaceCategories()
end
function MessageBox:renderCategories()
-- Convert category tables to strings and pass them through
-- [[Module:Category handler]].
return categoryHandler{
main = table.concat(self.categories[0] or {}),
template = table.concat(self.categories[10] or {}),
all = table.concat(self.categories.all or {}),
nocat = self.args.nocat,
page = self.args.page
}
end
function MessageBox:export()
local root = mw.html.create()
-- Add the subst check error.
if self.isSubstituted and self.name then
root:tag('b')
:addClass('error')
:wikitext(string.format(
'Шаблон <code>%s[[Шаблон:%s|%s]]%s</code> был неккоректно подставлен.',
mw.text.nowiki('{{'), self.name, self.name, mw.text.nowiki('}}')
))
end
-- Create the box table.
local boxTable = root:tag('table')
boxTable:attr('id', self.id or nil)
for i, class in ipairs(self.classes or {}) do
boxTable:addClass(class or nil)
end
boxTable
:cssText(self.style or nil)
:attr('role', 'presentation')
if self.dataLabel1 then
boxTable:attr('data-' .. self.dataLabel1, self.dataValue1)
end
if self.dataLabel2 then
boxTable:attr('data-' .. self.dataLabel2, self.dataValue2)
end
if self.dataLabel3 then
boxTable:attr('data-' .. self.dataLabel3, self.dataValue3)
end
if self.attrs then
boxTable:attr(self.attrs)
end
-- Add the left-hand image.
local row = boxTable:tag('tr')
if self.imageLeft then
local imageLeftCell = row:tag('td'):addClass('mbox-image')
if self.imageCellDiv then
-- If we are using a div, redefine imageLeftCell so that the image
-- is inside it. Divs use style="width: 52px;", which limits the
-- image width to 52px. If any images in a div are wider than that,
-- they may overlap with the text or cause other display problems.
imageLeftCell = imageLeftCell:tag('div'):css('width', '52px')
end
imageLeftCell:wikitext(self.imageLeft or nil)
elseif self.imageEmptyCell then
-- Some message boxes define an empty cell if no image is specified, and
-- some don't. The old template code in templates where empty cells are
-- specified gives the following hint: "No image. Cell with some width
-- or padding necessary for text cell to have 100% width."
row:tag('td')
:addClass('mbox-empty-cell')
:cssText(self.imageEmptyCellStyle or nil)
end
-- Add the text.
local textCell = row:tag('td'):addClass('mbox-text')
if self.useCollapsibleTextFields then
-- The message box uses advanced text parameters that allow things to be
-- collapsible. At the moment, only ambox uses this.
textCell:cssText(self.textstyle or nil)
local textCellDiv = textCell:tag('div')
textCellDiv
:addClass('mbox-text-div')
:wikitext(self.issue or nil)
local textsmallCellDiv = textCell:tag('div')
textsmallCellDiv
:addClass('mbox-textsmall-div hide-when-compact')
:cssText(self.textsmallstyle or 'font-size:85%')
:wikitext(self.textsmall or nil)
if (self.talk or self.fix) and not self.isSmall then
textsmallCellDiv:tag('span')
:addClass('hide-when-compact')
:wikitext(self.talk and (' ' .. self.talk) or nil)
:wikitext(self.fix and (' ' .. self.fix) or nil)
end
textsmallCellDiv:wikitext(self.date and (' ' .. self.date) or nil)
if self.info and not self.isSmall then
textsmallCellDiv
:tag('span')
:addClass('hide-when-compact')
:wikitext(self.info and (' ' .. self.info) or nil)
end
if self.removalNotice then
textsmallCellDiv:tag('small')
:addClass('hide-when-compact')
:tag('i')
:wikitext(string.format(" (%s)", self.removalNotice))
end
if self.shortFix then
textCell:tag('div')
:addClass('mbox-multiply')
:tag('span')
:wikitext(string.format("%s", self.shortFix))
:tag('span')
:wikitext(self.date and (' ' .. self.date) or nil)
end
else
-- Default text formatting - anything goes.
textCell
:cssText(self.textstyle or nil)
:wikitext(self.text or nil)
end
-- Add the right-hand image.
if self.imageRight then
local imageRightCell = row:tag('td'):addClass('mbox-imageright')
if self.imageCellDiv then
-- If we are using a div, redefine imageRightCell so that the image
-- is inside it.
imageRightCell = imageRightCell:tag('div'):css('width', '52px')
end
imageRightCell
:wikitext(self.imageRight or nil)
end
-- Add the below row.
if self.below then
boxTable:tag('tr')
:tag('td')
:attr('colspan', self.imageRight and '3' or '2')
:addClass('mbox-text')
:cssText(self.textstyle or nil)
:wikitext(self.below or nil)
end
-- Add error message for invalid type parameters.
if self.invalidTypeError then
root:tag('div')
:css('text-align', 'center')
:wikitext(string.format(
'Этот шаблон-сообщение использует неверный параметр "type=%s", необходимо исправить.',
self.type or ''
))
end
-- Add categories.
root:wikitext(self:renderCategories() or nil)
return tostring(root)
end
--------------------------------------------------------------------------------
-- Exports
--------------------------------------------------------------------------------
local p, mt = {}, {}
function p._exportClasses()
-- For testing.
return {
MessageBox = MessageBox
}
end
function p.main(boxType, args, cfgTables)
local box = MessageBox.new(boxType, args, cfgTables or mw.loadData(CONFIG_MODULE))
box:setParameters()
box:setCategories()
return box:export()
end
function mt.__index(t, k)
return function (frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
return t.main(k, getArgs(frame, {trim = false, removeBlanks = false}))
end
end
return setmetatable(p, mt)
f7438b70acb7f9253502968228af5c073b3b1ca5
Модуль:Message box/configuration
828
67
625
2021-07-29T21:08:17Z
ruwiki>WerySkok
0
1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии.
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Message box configuration --
-- --
-- This module contains configuration data for [[Module:Message box]]. --
--------------------------------------------------------------------------------
return {
ambox = {
types = {
speedy = {
class = 'ambox-speedy',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'ambox-delete',
image = 'Stop hand nuvola.svg'
},
content = {
class = 'ambox-content',
image = 'Emblem-important.svg'
},
style = {
class = 'ambox-style',
image = 'Broom_icon.svg'
},
move = {
class = 'ambox-move',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'ambox-protection',
image = 'Padlock-silver-medium.svg'
},
notice = {
class = 'ambox-notice',
image = 'Information.svg'
},
good = {
class = 'ambox-good',
image = 'Green star boxed.svg'
},
serious = {
class = 'ambox-serious',
image = 'Stop hand nuvola.svg'
},
merge = {
class = 'ambox-merge',
image = 'Merge-split-transwiki default.svg'
},
discussion = {
class = 'ambox-discussion',
image = 'Nuvola apps ksirc.png'
}
},
default = 'notice',
allowBlankParams = {'talk', 'sect', 'date', 'issue', 'fix', 'subst', 'hidden', 'image'},
allowSmall = true,
smallParam = 'left',
smallClass = 'mbox-small-left',
substCheck = true,
classes = {'metadata', 'ambox'},
imageEmptyCell = true,
imageCheckBlank = true,
imageSmallSize = '20x20px',
imageCellDiv = true,
useCollapsibleTextFields = true,
imageRightNone = true,
sectionDefault = 'статья',
allowMainspaceCategories = true,
templateCategory = 'Шаблоны:Шаблоны-сообщения для статей',
templateCategoryRequireName = true,
templateErrorCategory = 'Шаблоны:Шаблоны-сообщения для статей с пропущенными параметрами',
templateErrorParamsToCheck = {'issue', 'fix'},
removalNotice = '[[Help:Maintenance template removal|Learn how and when to remove this template message]]'
},
cmbox = {
types = {
speedy = {
class = 'cmbox-speedy',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'cmbox-delete',
image = 'Ambox warning pn.svg'
},
content = {
class = 'cmbox-content',
image = 'Ambox important.svg'
},
style = {
class = 'cmbox-style',
image = 'Edit-clear.svg'
},
move = {
class = 'cmbox-move',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'cmbox-protection',
image = 'Padlock-silver-medium.svg'
},
notice = {
class = 'cmbox-notice',
image = 'Information icon4.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'cmbox'},
imageEmptyCell = true,
useCollapsibleTextFields = true
},
fmbox = {
types = {
warning = {
class = 'fmbox-warning',
image = 'Ambox warning pn.svg'
},
editnotice = {
class = 'fmbox-editnotice',
image = 'Information icon4.svg'
},
system = {
class = 'fmbox-system',
image = 'Information icon4.svg'
}
},
default = 'system',
showInvalidTypeError = true,
classes = {'fmbox'},
imageEmptyCell = false,
imageRightNone = false,
useCollapsibleTextFields = true
},
imbox = {
types = {
speedy = {
class = 'imbox-speedy',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'imbox-delete',
image = 'Ambox warning pn.svg'
},
content = {
class = 'imbox-content',
image = 'Ambox important.svg'
},
style = {
class = 'imbox-style',
image = 'Edit-clear.svg'
},
move = {
class = 'imbox-move',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'imbox-protection',
image = 'Padlock-silver-medium.svg'
},
license = {
class = 'imbox-license licensetpl',
image = 'Imbox license.png' -- @todo We need an SVG version of this
},
featured = {
class = 'imbox-featured',
image = 'Cscr-featured.svg'
},
notice = {
class = 'imbox-notice',
image = 'Information icon4.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'imbox'},
imageEmptyCell = true,
below = true,
useCollapsibleTextFields = true,
templateCategory = 'Шаблоны:Шаблоны-сообщения для файлов'
},
ombox = {
types = {
speedy = {
class = 'ombox-speedy',
image = 'OOjs UI icon alert-destructive.svg'
},
delete = {
class = 'ombox-delete',
image = 'OOjs UI icon alert-destructive.svg'
},
content = {
class = 'ombox-content',
image = 'OOjs UI icon notice-warning.svg'
},
style = {
class = 'ombox-style',
image = 'Edit-clear.svg'
},
move = {
class = 'ombox-move',
image = 'Imbox move.png'
},
protection = {
class = 'ombox-protection',
image = 'Imbox protection.png'
},
notice = {
class = 'ombox-notice',
image = 'OOjs UI icon info-progressive.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'ombox'},
allowSmall = true,
imageEmptyCell = true,
imageRightNone = true,
useCollapsibleTextFields = true
},
tmbox = {
types = {
speedy = {
class = 'tmbox-speedy',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'tmbox-delete',
image = 'Ambox warning pn.svg'
},
content = {
class = 'tmbox-content',
image = 'Ambox important.svg'
},
style = {
class = 'tmbox-style',
image = 'Edit-clear.svg'
},
move = {
class = 'tmbox-move',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'tmbox-protection',
image = 'Padlock-silver-medium.svg'
},
notice = {
class = 'tmbox-notice',
image = 'Information icon4.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'tmbox'},
allowSmall = true,
imageRightNone = true,
imageEmptyCell = true,
imageEmptyCellStyle = true,
useCollapsibleTextFields = true,
templateCategory = 'Шаблоны:Шаблоны-сообщения для страниц обсуждений'
}
}
569b6dcbf9ec9858c77ddf8aefe198cd3f90a950
Модуль:Namespace detect/config
828
77
627
126
2021-07-29T21:08:18Z
ruwiki>WerySkok
0
1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии.
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Namespace detect configuration data --
-- --
-- This module stores configuration data for Module:Namespace detect. Here --
-- you can localise the module to your wiki's language. --
-- --
-- To activate a configuration item, you need to uncomment it. This means --
-- that you need to remove the text "-- " at the start of the line. --
--------------------------------------------------------------------------------
local cfg = {} -- Don't edit this line.
--------------------------------------------------------------------------------
-- Parameter names --
-- These configuration items specify custom parameter names. Values added --
-- here will work in addition to the default English parameter names. --
-- To add one extra name, you can use this format: --
-- --
-- cfg.foo = 'parameter name' --
-- --
-- To add multiple names, you can use this format: --
-- --
-- cfg.foo = {'parameter name 1', 'parameter name 2', 'parameter name 3'} --
--------------------------------------------------------------------------------
---- This parameter displays content for the main namespace:
-- cfg.main = 'main'
---- This parameter displays in talk namespaces:
-- cfg.talk = 'talk'
---- This parameter displays content for "other" namespaces (namespaces for which
---- parameters have not been specified):
-- cfg.other = 'other'
---- This parameter makes talk pages behave as though they are the corresponding
---- subject namespace. Note that this parameter is used with [[Module:Yesno]].
---- Edit that module to change the default values of "yes", "no", etc.
-- cfg.subjectns = 'subjectns'
---- This parameter sets a demonstration namespace:
-- cfg.demospace = 'demospace'
---- This parameter sets a specific page to compare:
cfg.demopage = 'page'
--------------------------------------------------------------------------------
-- Table configuration --
-- These configuration items allow customisation of the "table" function, --
-- used to generate a table of possible parameters in the module --
-- documentation. --
--------------------------------------------------------------------------------
---- The header for the namespace column in the wikitable containing the list of
---- possible subject-space parameters.
-- cfg.wikitableNamespaceHeader = 'Namespace'
---- The header for the wikitable containing the list of possible subject-space
---- parameters.
-- cfg.wikitableAliasesHeader = 'Aliases'
--------------------------------------------------------------------------------
-- End of configuration data --
--------------------------------------------------------------------------------
return cfg -- Don't edit this line.
0e4ff08d13c4b664d66b32c232deb129b77c1a56
Модуль:Namespace detect/data
828
76
629
124
2021-07-29T21:08:19Z
ruwiki>WerySkok
0
1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии.
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Namespace detect data --
-- This module holds data for [[Module:Namespace detect]] to be loaded per --
-- page, rather than per #invoke, for performance reasons. --
--------------------------------------------------------------------------------
local cfg = require('Module:Namespace detect/config')
local function addKey(t, key, defaultKey)
if key ~= defaultKey then
t[#t + 1] = key
end
end
-- Get a table of parameters to query for each default parameter name.
-- This allows wikis to customise parameter names in the cfg table while
-- ensuring that default parameter names will always work. The cfg table
-- values can be added as a string, or as an array of strings.
local defaultKeys = {
'main',
'talk',
'other',
'subjectns',
'demospace',
'demopage'
}
local argKeys = {}
for i, defaultKey in ipairs(defaultKeys) do
argKeys[defaultKey] = {defaultKey}
end
for defaultKey, t in pairs(argKeys) do
local cfgValue = cfg[defaultKey]
local cfgValueType = type(cfgValue)
if cfgValueType == 'string' then
addKey(t, cfgValue, defaultKey)
elseif cfgValueType == 'table' then
for i, key in ipairs(cfgValue) do
addKey(t, key, defaultKey)
end
end
cfg[defaultKey] = nil -- Free the cfg value as we don't need it any more.
end
local function getParamMappings()
--[[
-- Returns a table of how parameter names map to namespace names. The keys
-- are the actual namespace names, in lower case, and the values are the
-- possible parameter names for that namespace, also in lower case. The
-- table entries are structured like this:
-- {
-- [''] = {'main'},
-- ['wikipedia'] = {'wikipedia', 'project', 'wp'},
-- ...
-- }
--]]
local mappings = {}
local mainNsName = mw.site.subjectNamespaces[0].name
mainNsName = mw.ustring.lower(mainNsName)
mappings[mainNsName] = mw.clone(argKeys.main)
mappings['talk'] = mw.clone(argKeys.talk)
for nsid, ns in pairs(mw.site.subjectNamespaces) do
if nsid ~= 0 then -- Exclude main namespace.
local nsname = mw.ustring.lower(ns.name)
local canonicalName = mw.ustring.lower(ns.canonicalName)
mappings[nsname] = {nsname}
if canonicalName ~= nsname then
table.insert(mappings[nsname], canonicalName)
end
for _, alias in ipairs(ns.aliases) do
table.insert(mappings[nsname], mw.ustring.lower(alias))
end
end
end
return mappings
end
return {
argKeys = argKeys,
cfg = cfg,
mappings = getParamMappings()
}
d224f42a258bc308ef3ad8cc8686cd7a4f47d005
Модуль:No globals
828
251
607
2021-07-29T21:08:20Z
ruwiki>WerySkok
0
1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии.
Scribunto
text/plain
local mt = getmetatable(_G) or {}
function mt.__index (t, k)
if k ~= 'arg' then
error('Tried to read nil global ' .. tostring(k), 2)
end
return nil
end
function mt.__newindex(t, k, v)
if k ~= 'arg' then
error('Tried to write global ' .. tostring(k), 2)
end
rawset(t, k, v)
end
setmetatable(_G, mt)
8ce3969f7d53b08bd00dabe4cc9780bc6afd412a
Модуль:Separated entries
828
158
565
358
2021-07-29T21:08:21Z
ruwiki>WerySkok
0
1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии.
Scribunto
text/plain
-- This module takes positional parameters as input and concatenates them with
-- an optional separator. The final separator (the "conjunction") can be
-- specified independently, enabling natural-language lists like
-- "foo, bar, baz and qux".
local compressSparseArray = require('Module:TableTools').compressSparseArray
local p = {}
function p._main(args)
local separator = args.separator
-- Decode (convert to Unicode) HTML escape sequences, such as " " for space.
and mw.text.decode(args.separator) or ''
local conjunction = args.conjunction and mw.text.decode(args.conjunction) or separator
-- Discard named parameters.
local values = compressSparseArray(args)
return mw.text.listToText(values, separator, conjunction)
end
local function makeInvokeFunction(separator, conjunction)
return function (frame)
local args = require('Module:Arguments').getArgs(frame)
args.separator = separator or args.separator
args.conjunction = conjunction or args.conjunction
return p._main(args)
end
end
p.main = makeInvokeFunction()
p.br = makeInvokeFunction('<br />')
p.newline = makeInvokeFunction('\n')
p.comma = makeInvokeFunction(mw.message.new('comma-separator'):plain())
return p
33a68f0a46d62c42b6523a548f0f881e82ecfe58
Модуль:String
828
138
567
318
2021-07-29T21:08:21Z
ruwiki>WerySkok
0
1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии.
Scribunto
text/plain
--[[
This module is intended to provide access to basic string functions.
Most of the functions provided here can be invoked with named parameters,
unnamed parameters, or a mixture. If named parameters are used, Mediawiki will
automatically remove any leading or trailing whitespace from the parameter.
Depending on the intended use, it may be advantageous to either preserve or
remove such whitespace.
Global options
ignore_errors: If set to 'true' or 1, any error condition will result in
an empty string being returned rather than an error message.
error_category: If an error occurs, specifies the name of a category to
include with the error message. The default category is
[Category:Errors reported by Module String].
no_category: If set to 'true' or 1, no category will be added if an error
is generated.
Unit tests for this module are available at Module:String/tests.
]]
local str = {}
--[[
subcount
This function returns the count of substring in source string.
Usage:
{{#invoke:String|subcount|source_string|substring|plain_flag}}
OR
{{#invoke:String|subcount|s=source_string|pattern=substring|plain=plain_flag}}
Parameters
s: The string to search
pattern: The pattern or string to find within the string
plain: A flag indicating that the substring should be understood as plain
text. Defaults to true.
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the target string.
]]
function str.subcount( frame )
local new_args = str._getParameters( frame.args, {'s', 'pattern', 'plain'} );
local s = new_args['s'] or '';
local plain_flag = str._getBoolean( new_args['plain'] or true );
local pattern = new_args['pattern'] or '';
if s == '' or pattern == '' then
return 0;
end
if plain_flag then
pattern = str._escapePattern( pattern );
end
local _, count = mw.ustring.gsub(s, pattern, "")
return count;
end
--[[
len
This function returns the length of the target string.
Usage:
{{#invoke:String|len|target_string|}}
OR
{{#invoke:String|len|s=target_string}}
Parameters
s: The string whose length to report
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the target string.
]]
function str.len( frame )
local new_args = str._getParameters( frame.args, {'s'} );
local s = new_args['s'] or '';
return mw.ustring.len( s )
end
--[[
sub
This function returns a substring of the target string at specified indices.
Usage:
{{#invoke:String|sub|target_string|start_index|end_index}}
OR
{{#invoke:String|sub|s=target_string|i=start_index|j=end_index}}
Parameters
s: The string to return a subset of
i: The fist index of the substring to return, defaults to 1.
j: The last index of the string to return, defaults to the last character.
The first character of the string is assigned an index of 1. If either i or j
is a negative value, it is interpreted the same as selecting a character by
counting from the end of the string. Hence, a value of -1 is the same as
selecting the last character of the string.
If the requested indices are out of range for the given string, an error is
reported.
]]
function str.sub( frame )
local new_args = str._getParameters( frame.args, { 's', 'i', 'j' } );
local s = new_args['s'] or '';
local i = tonumber( new_args['i'] ) or 1;
local j = tonumber( new_args['j'] ) or -1;
local len = mw.ustring.len( s );
-- Convert negatives for range checking
if i < 0 then
i = len + i + 1;
end
if j < 0 then
j = len + j + 1;
end
if i > len or j > len or i < 1 or j < 1 then
return str._error( 'Значение индекса подстроки выходит за допустимые границы' );
end
if j < i then
return str._error( 'Неверный порядок индексов подстроки' );
end
return mw.ustring.sub( s, i, j )
end
--[[
This function implements that features of {{str sub old}} and is kept in order
to maintain these older templates.
]]
function str.sublength( frame )
local i = tonumber( frame.args.i ) or 0
local len = tonumber( frame.args.len )
return mw.ustring.sub( frame.args.s, i + 1, len and ( i + len ) )
end
--[[
match
This function returns a substring from the source string that matches a
specified pattern.
Usage:
{{#invoke:String|match|source_string|pattern_string|start_index|match_number|plain_flag|nomatch_output}}
OR
{{#invoke:String|pos|s=source_string|pattern=pattern_string|start=start_index
|match=match_number|plain=plain_flag|nomatch=nomatch_output}}
Parameters
s: The string to search
pattern: The pattern or string to find within the string
start: The index within the source string to start the search. The first
character of the string has index 1. Defaults to 1.
match: In some cases it may be possible to make multiple matches on a single
string. This specifies which match to return, where the first match is
match= 1. If a negative number is specified then a match is returned
counting from the last match. Hence match = -1 is the same as requesting
the last match. Defaults to 1.
plain: A flag indicating that the pattern should be understood as plain
text. Defaults to false.
nomatch: If no match is found, output the "nomatch" value rather than an error.
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from each string. In some circumstances this is desirable, in
other cases one may want to preserve the whitespace.
If the match_number or start_index are out of range for the string being queried, then
this function generates an error. An error is also generated if no match is found.
If one adds the parameter ignore_errors=true, then the error will be suppressed and
an empty string will be returned on any failure.
For information on constructing Lua patterns, a form of [regular expression], see:
* http://www.lua.org/manual/5.1/manual.html#5.4.1
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Ustring_patterns
]]
function str.match( frame )
local new_args = str._getParameters( frame.args, {'s', 'pattern', 'start', 'match', 'plain', 'nomatch'} );
local s = new_args['s'] or '';
local start = tonumber( new_args['start'] ) or 1;
local plain_flag = str._getBoolean( new_args['plain'] or false );
local pattern = new_args['pattern'] or '';
local match_index = math.floor( tonumber(new_args['match']) or 1 );
local nomatch = new_args['nomatch'];
if s == '' then
return str._error( 'Пустая строка поиска' );
end
if pattern == '' then
return str._error( 'Пустой шаблон поиска' );
end
if math.abs(start) < 1 or math.abs(start) > mw.ustring.len( s ) then
return str._error( 'Индекс начала поиска выходит за допустимые границы' );
end
if match_index == 0 then
return str._error( 'Индекс совпадения выходит за допустимые границы' );
end
if plain_flag then
pattern = str._escapePattern( pattern );
end
local result
if match_index == 1 then
-- Find first match is simple case
result = mw.ustring.match( s, pattern, start )
else
if start > 1 then
s = mw.ustring.sub( s, start );
end
local iterator = mw.ustring.gmatch(s, pattern);
if match_index > 0 then
-- Forward search
for w in iterator do
match_index = match_index - 1;
if match_index == 0 then
result = w;
break;
end
end
else
-- Reverse search
local result_table = {};
local count = 1;
for w in iterator do
result_table[count] = w;
count = count + 1;
end
result = result_table[ count + match_index ];
end
end
if result == nil then
if nomatch == nil then
return str._error( 'Совпадение не найдено' );
else
return nomatch;
end
else
return result;
end
end
--[[
pos
This function returns a single character from the target string at position pos.
Usage:
{{#invoke:String|pos|target_string|index_value}}
OR
{{#invoke:String|pos|target=target_string|pos=index_value}}
Parameters
target: The string to search
pos: The index for the character to return
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the target string. In some circumstances this is desirable, in
other cases one may want to preserve the whitespace.
The first character has an index value of 1.
If one requests a negative value, this function will select a character by counting backwards
from the end of the string. In other words pos = -1 is the same as asking for the last character.
A requested value of zero, or a value greater than the length of the string returns an error.
]]
function str.pos( frame )
local new_args = str._getParameters( frame.args, {'target', 'pos'} );
local target_str = new_args['target'] or '';
local pos = tonumber( new_args['pos'] ) or 0;
if pos == 0 or math.abs(pos) > mw.ustring.len( target_str ) then
return str._error( 'Значение индекса строки выходит за допустимые границы' );
end
return mw.ustring.sub( target_str, pos, pos );
end
--[[
str_find
This function duplicates the behavior of {{str_find}}, including all of its quirks.
This is provided in order to support existing templates, but is NOT RECOMMENDED for
new code and templates. New code is recommended to use the "find" function instead.
Returns the first index in "source" that is a match to "target". Indexing is 1-based,
and the function returns -1 if the "target" string is not present in "source".
Important Note: If the "target" string is empty / missing, this function returns a
value of "1", which is generally unexpected behavior, and must be accounted for
separatetly.
]]
function str.str_find( frame )
local new_args = str._getParameters( frame.args, {'source', 'target'} );
local source_str = new_args['source'] or '';
local target_str = new_args['target'] or '';
if target_str == '' then
return 1;
end
local start = mw.ustring.find( source_str, target_str, 1, true )
if start == nil then
start = -1
end
return start
end
--[[
find
This function allows one to search for a target string or pattern within another
string.
Usage:
{{#invoke:String|find|source_str|target_string|start_index|plain_flag}}
OR
{{#invoke:String|find|source=source_str|target=target_str|start=start_index|plain=plain_flag}}
Parameters
source: The string to search
target: The string or pattern to find within source
start: The index within the source string to start the search, defaults to 1
plain: Boolean flag indicating that target should be understood as plain
text and not as a Lua style regular expression, defaults to true
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the parameter. In some circumstances this is desirable, in
other cases one may want to preserve the whitespace.
This function returns the first index >= "start" where "target" can be found
within "source". Indices are 1-based. If "target" is not found, then this
function returns 0. If either "source" or "target" are missing / empty, this
function also returns 0.
This function should be safe for UTF-8 strings.
]]
function str.find( frame )
local new_args = str._getParameters( frame.args, {'source', 'target', 'start', 'plain' } );
local source_str = new_args['source'] or '';
local pattern = new_args['target'] or '';
local start_pos = tonumber(new_args['start']) or 1;
local plain = new_args['plain'] or true;
if source_str == '' or pattern == '' then
return 0;
end
plain = str._getBoolean( plain );
local start = mw.ustring.find( source_str, pattern, start_pos, plain )
if start == nil then
start = 0
end
return start
end
--[[
replace
This function allows one to replace a target string or pattern within another
string.
Usage:
{{#invoke:String|replace|source_str|pattern_string|replace_string|replacement_count|plain_flag}}
OR
{{#invoke:String|replace|source=source_string|pattern=pattern_string|replace=replace_string|
count=replacement_count|plain=plain_flag}}
Parameters
source: The string to search
pattern: The string or pattern to find within source
replace: The replacement text
count: The number of occurences to replace, defaults to all.
plain: Boolean flag indicating that pattern should be understood as plain
text and not as a Lua style regular expression, defaults to true
]]
function str.replace( frame )
local new_args = str._getParameters( frame.args, {'source', 'pattern', 'replace', 'count', 'plain' } );
local source_str = new_args['source'] or '';
local pattern = new_args['pattern'] or '';
local replace = new_args['replace'] or '';
local count = tonumber( new_args['count'] );
local plain = new_args['plain'] or true;
if source_str == '' or pattern == '' then
return source_str;
end
plain = str._getBoolean( plain );
if plain then
pattern = str._escapePattern( pattern );
replace = mw.ustring.gsub( replace, "%%", "%%%%" ); --Only need to escape replacement sequences.
end
local result;
if count ~= nil then
result = mw.ustring.gsub( source_str, pattern, replace, count );
else
result = mw.ustring.gsub( source_str, pattern, replace );
end
return result;
end
--[[
This function adds support for escaping parts of the patterns when using [plain=false].
]]
function str.escape( frame )
local new_args = str._getParameters( frame.args, {'pattern' } );
local pattern = new_args['pattern'] or '';
local result = '';
result = str._escapePattern( pattern );
return result;
end
--[[
Internal compare string function
]]
function str._strcmp(a , b)
local s1c = mw.ustring.gcodepoint( a );
local s2c = mw.ustring.gcodepoint( b );
while true do
local c1 = s1c();
local c2 = s2c();
if c1 == nil then
if c2 == nil then
return 0
else
return -1
end
else
if c2 ~= nil then
if c1 ~= c2 then
return c1 < c2 and -1 or 1
end
else
return 1
end
end
end
return 0
end
--[[
compare
This function compare two UTF-8 strings
Usage:
{{#invoke:String|compare|str1|str2}}
Returns:
0 - if strings are equal
1 - if st1 > str2
-1 - if str1 < str2
]]
function str.compare(frame)
local str1 = frame.args[1] or '';
local str2 = frame.args[2] or '';
return str._strcmp(str1 , str2)
end
--[[
simple function to pipe string.rep to templates.
]]
function str.rep( frame )
local repetitions = tonumber( frame.args[2] )
if not repetitions then
return str._error( 'функция rep ожидает число во втором параметре, а получено "' .. ( frame.args[2] or '' ) .. '"' )
end
return string.rep( frame.args[1] or '', repetitions )
end
--[[
Helper function that populates the argument list given that user may need to use a mix of
named and unnamed parameters. This is relevant because named parameters are not
identical to unnamed parameters due to string trimming, and when dealing with strings
we sometimes want to either preserve or remove that whitespace depending on the application.
]]
function str._getParameters( frame_args, arg_list )
local new_args = {};
local index = 1;
local value;
for i,arg in ipairs( arg_list ) do
value = frame_args[arg]
if value == nil then
value = frame_args[index];
index = index + 1;
end
new_args[arg] = value;
end
return new_args;
end
--[[
Helper function to handle error messages.
]]
function str._error( error_str )
local frame = mw.getCurrentFrame();
local error_category = frame.args.error_category or 'Страницы с ошибками модуля String';
local ignore_errors = frame.args.ignore_errors or false;
local no_category = frame.args.no_category or false;
if str._getBoolean(ignore_errors) then
return '';
end
local error_str = '<strong class="error">Ошибка модуля String: ' .. error_str .. '</strong>';
if error_category ~= '' and not str._getBoolean( no_category ) then
error_str = '[[Категория:' .. error_category .. ']]' .. error_str;
end
return error_str;
end
--[[
Helper Function to interpret boolean strings
]]
function str._getBoolean( boolean_str )
local boolean_value;
if type( boolean_str ) == 'string' then
boolean_str = boolean_str:lower();
if boolean_str == 'false' or boolean_str == 'no' or boolean_str == '0'
or boolean_str == '' then
boolean_value = false;
else
boolean_value = true;
end
elseif type( boolean_str ) == 'boolean' then
boolean_value = boolean_str;
else
error( 'Логическое значение не найдено' );
end
return boolean_value
end
--[[
Helper function that escapes all pattern characters so that they will be treated
as plain text.
]]
function str._escapePattern( pattern_str )
return mw.ustring.gsub( pattern_str, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" );
end
return str
b4a4e099d7fab23576bae7af327a44c87d13f9cb
Модуль:TableTools
828
125
569
292
2021-07-29T21:08:22Z
ruwiki>WerySkok
0
1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии.
Scribunto
text/plain
--[[
------------------------------------------------------------------------------------
-- TableTools --
-- --
-- This module includes a number of functions for dealing with Lua tables. --
-- It is a meta-module, meant to be called from other Lua modules, and should --
-- not be called directly from #invoke. --
------------------------------------------------------------------------------------
--]]
local libraryUtil = require('libraryUtil')
local p = {}
-- Define often-used variables and functions.
local floor = math.floor
local infinity = math.huge
local checkType = libraryUtil.checkType
local checkTypeMulti = libraryUtil.checkTypeMulti
--[[
------------------------------------------------------------------------------------
-- isPositiveInteger
--
-- This function returns true if the given value is a positive integer, and false
-- if not. Although it doesn't operate on tables, it is included here as it is
-- useful for determining whether a given table key is in the array part or the
-- hash part of a table.
------------------------------------------------------------------------------------
--]]
function p.isPositiveInteger(v)
if type(v) == 'number' and v >= 1 and floor(v) == v and v < infinity then
return true
else
return false
end
end
--[[
------------------------------------------------------------------------------------
-- isNan
--
-- This function returns true if the given number is a NaN value, and false
-- if not. Although it doesn't operate on tables, it is included here as it is
-- useful for determining whether a value can be a valid table key. Lua will
-- generate an error if a NaN is used as a table key.
------------------------------------------------------------------------------------
--]]
function p.isNan(v)
if type(v) == 'number' and tostring(v) == '-nan' then
return true
else
return false
end
end
--[[
------------------------------------------------------------------------------------
-- shallowClone
--
-- This returns a clone of a table. The value returned is a new table, but all
-- subtables and functions are shared. Metamethods are respected, but the returned
-- table will have no metatable of its own.
------------------------------------------------------------------------------------
--]]
function p.shallowClone(t)
local ret = {}
for k, v in pairs(t) do
ret[k] = v
end
return ret
end
--[[
------------------------------------------------------------------------------------
-- removeDuplicates
--
-- This removes duplicate values from an array. Non-positive-integer keys are
-- ignored. The earliest value is kept, and all subsequent duplicate values are
-- removed, but otherwise the array order is unchanged.
------------------------------------------------------------------------------------
--]]
function p.removeDuplicates(t)
checkType('removeDuplicates', 1, t, 'table')
local isNan = p.isNan
local ret, exists = {}, {}
for i, v in ipairs(t) do
if isNan(v) then
-- NaNs can't be table keys, and they are also unique, so we don't need to check existence.
ret[#ret + 1] = v
else
if not exists[v] then
ret[#ret + 1] = v
exists[v] = true
end
end
end
return ret
end
--[[
------------------------------------------------------------------------------------
-- numKeys
--
-- This takes a table and returns an array containing the numbers of any numerical
-- keys that have non-nil values, sorted in numerical order.
------------------------------------------------------------------------------------
--]]
function p.numKeys(t)
checkType('numKeys', 1, t, 'table')
local isPositiveInteger = p.isPositiveInteger
local nums = {}
for k, v in pairs(t) do
if isPositiveInteger(k) then
nums[#nums + 1] = k
end
end
table.sort(nums)
return nums
end
--[[
------------------------------------------------------------------------------------
-- affixNums
--
-- This takes a table and returns an array containing the numbers of keys with the
-- specified prefix and suffix. For example, for the table
-- {a1 = 'foo', a3 = 'bar', a6 = 'baz'} and the prefix "a", affixNums will
-- return {1, 3, 6}.
------------------------------------------------------------------------------------
--]]
function p.affixNums(t, prefix, suffix)
checkType('affixNums', 1, t, 'table')
checkType('affixNums', 2, prefix, 'string', true)
checkType('affixNums', 3, suffix, 'string', true)
local function cleanPattern(s)
-- Cleans a pattern so that the magic characters ()%.[]*+-?^$ are interpreted literally.
s = s:gsub('([%(%)%%%.%[%]%*%+%-%?%^%$])', '%%%1')
return s
end
prefix = prefix or ''
suffix = suffix or ''
prefix = cleanPattern(prefix)
suffix = cleanPattern(suffix)
local pattern = '^' .. prefix .. '([1-9]%d*)' .. suffix .. '$'
local nums = {}
for k, v in pairs(t) do
if type(k) == 'string' then
local num = mw.ustring.match(k, pattern)
if num then
nums[#nums + 1] = tonumber(num)
end
end
end
table.sort(nums)
return nums
end
--[[
------------------------------------------------------------------------------------
-- numData
--
-- Given a table with keys like ("foo1", "bar1", "foo2", "baz2"), returns a table
-- of subtables in the format
-- { [1] = {foo = 'text', bar = 'text'}, [2] = {foo = 'text', baz = 'text'} }
-- Keys that don't end with an integer are stored in a subtable named "other".
-- The compress option compresses the table so that it can be iterated over with
-- ipairs.
------------------------------------------------------------------------------------
--]]
function p.numData(t, compress)
checkType('numData', 1, t, 'table')
checkType('numData', 2, compress, 'boolean', true)
local ret = {}
for k, v in pairs(t) do
local prefix, num = mw.ustring.match(tostring(k), '^([^0-9]*)([1-9][0-9]*)$')
if num then
num = tonumber(num)
local subtable = ret[num] or {}
if prefix == '' then
-- Positional parameters match the blank string; put them at the start of the subtable instead.
prefix = 1
end
subtable[prefix] = v
ret[num] = subtable
else
local subtable = ret.other or {}
subtable[k] = v
ret.other = subtable
end
end
if compress then
local other = ret.other
ret = p.compressSparseArray(ret)
ret.other = other
end
return ret
end
--[[
------------------------------------------------------------------------------------
-- compressSparseArray
--
-- This takes an array with one or more nil values, and removes the nil values
-- while preserving the order, so that the array can be safely traversed with
-- ipairs.
------------------------------------------------------------------------------------
--]]
function p.compressSparseArray(t)
checkType('compressSparseArray', 1, t, 'table')
local ret = {}
local nums = p.numKeys(t)
for _, num in ipairs(nums) do
ret[#ret + 1] = t[num]
end
return ret
end
--[[
------------------------------------------------------------------------------------
-- sparseIpairs
--
-- This is an iterator for sparse arrays. It can be used like ipairs, but can
-- handle nil values.
------------------------------------------------------------------------------------
--]]
function p.sparseIpairs(t)
checkType('sparseIpairs', 1, t, 'table')
local nums = p.numKeys(t)
local i = 0
local lim = #nums
return function ()
i = i + 1
if i <= lim then
local key = nums[i]
return key, t[key]
else
return nil, nil
end
end
end
--[[
------------------------------------------------------------------------------------
-- size
--
-- This returns the size of a key/value pair table. It will also work on arrays,
-- but for arrays it is more efficient to use the # operator.
------------------------------------------------------------------------------------
--]]
function p.size(t)
checkType('size', 1, t, 'table')
local i = 0
for k in pairs(t) do
i = i + 1
end
return i
end
local function defaultKeySort(item1, item2)
-- "number" < "string", so numbers will be sorted before strings.
local type1, type2 = type(item1), type(item2)
if type1 ~= type2 then
return type1 < type2
else -- This will fail with table, boolean, function.
return item1 < item2
end
end
--[[
Returns a list of the keys in a table, sorted using either a default
comparison function or a custom keySort function.
]]
function p.keysToList(t, keySort, checked)
if not checked then
checkType('keysToList', 1, t, 'table')
checkTypeMulti('keysToList', 2, keySort, { 'function', 'boolean', 'nil' })
end
local list = {}
local index = 1
for key, value in pairs(t) do
list[index] = key
index = index + 1
end
if keySort ~= false then
keySort = type(keySort) == 'function' and keySort or defaultKeySort
table.sort(list, keySort)
end
return list
end
--[[
Iterates through a table, with the keys sorted using the keysToList function.
If there are only numerical keys, sparseIpairs is probably more efficient.
]]
function p.sortedPairs(t, keySort)
checkType('sortedPairs', 1, t, 'table')
checkType('sortedPairs', 2, keySort, 'function', true)
local list = p.keysToList(t, keySort, true)
local i = 0
return function()
i = i + 1
local key = list[i]
if key ~= nil then
return key, t[key]
else
return nil, nil
end
end
end
--[[
Returns true if all keys in the table are consecutive integers starting at 1.
--]]
function p.isArray(t)
checkType("isArray", 1, t, "table")
local i = 0
for k, v in pairs(t) do
i = i + 1
if t[i] == nil then
return false
end
end
return true
end
-- { "a", "b", "c" } -> { a = 1, b = 2, c = 3 }
function p.invert(array)
checkType("invert", 1, array, "table")
local map = {}
for i, v in ipairs(array) do
map[v] = i
end
return map
end
--[[
{ "a", "b", "c" } -> { ["a"] = true, ["b"] = true, ["c"] = true }
--]]
function p.listToSet(t)
checkType("listToSet", 1, t, "table")
local set = {}
for _, item in ipairs(t) do
set[item] = true
end
return set
end
--[[
Recursive deep copy function.
Preserves identities of subtables.
]]
local function _deepCopy(orig, includeMetatable, already_seen)
-- Stores copies of tables indexed by the original table.
already_seen = already_seen or {}
local copy = already_seen[orig]
if copy ~= nil then
return copy
end
if type(orig) == 'table' then
copy = {}
for orig_key, orig_value in pairs(orig) do
copy[deepcopy(orig_key, includeMetatable, already_seen)] = deepcopy(orig_value, includeMetatable, already_seen)
end
already_seen[orig] = copy
if includeMetatable then
local mt = getmetatable(orig)
if mt ~= nil then
local mt_copy = deepcopy(mt, includeMetatable, already_seen)
setmetatable(copy, mt_copy)
already_seen[mt] = mt_copy
end
end
else -- number, string, boolean, etc
copy = orig
end
return copy
end
function p.deepCopy(orig, noMetatable, already_seen)
checkType("deepCopy", 3, already_seen, "table", true)
return _deepCopy(orig, not noMetatable, already_seen)
end
--[[
Concatenates all values in the table that are indexed by a number, in order.
sparseConcat{ a, nil, c, d } => "acd"
sparseConcat{ nil, b, c, d } => "bcd"
]]
function p.sparseConcat(t, sep, i, j)
local list = {}
local list_i = 0
for _, v in p.sparseIpairs(t) do
list_i = list_i + 1
list[list_i] = v
end
return table.concat(list, sep, i, j)
end
--[[
-- This returns the length of a table, or the first integer key n counting from
-- 1 such that t[n + 1] is nil. It is similar to the operator #, but may return
-- a different value when there are gaps in the array portion of the table.
-- Intended to be used on data loaded with mw.loadData. For other tables, use #.
-- Note: #frame.args in frame object always be set to 0, regardless of
-- the number of unnamed template parameters, so use this function for
-- frame.args.
--]]
function p.length(t)
local i = 1
while t[i] ~= nil do
i = i + 1
end
return i - 1
end
function p.inArray(arr, valueToFind)
checkType("inArray", 1, arr, "table")
-- if valueToFind is nil, error?
for _, v in ipairs(arr) do
if v == valueToFind then
return true
end
end
return false
end
return p
fe918509f168332267834b3a6f5c219a9de5b2e7
Модуль:Template call code
828
126
571
2021-07-29T21:08:22Z
ruwiki>WerySkok
0
1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии.
Scribunto
text/plain
local getArgs = require('Module:Arguments').getArgs
local ru = mw.language.new('ru')
local p = {}
-- Используется для того, чтобы можно было удалять элементы из таблицы
local function copy(other)
local res = {}
for k, v in pairs(other) do
res[k] = v
end
return res
end
local function makeInvokeFunc(funcName)
return function (frame)
local args = copy(getArgs(frame, {
trim = false,
removeBlanks = false
}))
return p[funcName](args)
end
end
p.withoutParams = makeInvokeFunc('_withoutParams')
function p._withoutParams(args)
local name = args[1]
table.remove(args, 1)
-- Вещи типа «=» в первом параметре
if not name then
for k, v in pairs(args) do
if not k:find('^_') then
name = k .. '=' .. v
args[k] = nil
break
end
end
end
local flags = {}
for i, v in ipairs(args) do
if v == 'nl' or v == 'nolink' then
flags.noLink = true
elseif v == 's' then
flags.subst = true
elseif v == 'п' then
flags.podst = true
elseif v == 'g' then
flags.global = true
elseif v == 'nav' then
flags.nav = true
elseif v == 'noredir' then
flags.noRedirect = true
elseif v == 'u' then
flags.ucFirst = true
elseif v == 'b' then
flags.black = true
end
end
if name then
local trimmedName = mw.text.trim(name)
if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'subst:' then
flags.subst = true
name = mw.ustring.sub(trimmedName, 7)
end
if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'подст:' then
flags.podst = true
name = mw.ustring.sub(trimmedName, 7)
end
end
if args.text == '' then
args.text = nil
end
if args.comment == '' then
args.comment = nil
end
if args.lang == '' then
args.lang = nil
end
if args.sister == '' then
args.sister = nil
end
local currentTitle = mw.title.getCurrentTitle()
-- При опущенном первом параметре берём имя шаблона из названия страницы
if name == '' or not name then
local currentTitleRoot = currentTitle.rootText
if not flags.ucFirst and
((ru:uc(currentTitleRoot) ~= currentTitleRoot and
-- Книга:Литературное наследство, TranslateDate
not mw.ustring.match(currentTitleRoot, '^[А-Яа-яA-Za-z]+:?[А-ЯA-Z]')
) or
#currentTitleRoot == 1
)
then
name = ru:lcfirst(currentTitleRoot)
else
name = currentTitleRoot
end
end
local global = flags.global or mw.ustring.sub(name, 1, 1) == ':'
-- Начинаем собирать код
local linkBody, titleObject, linkBegin, linkDivider, linkEnd
local prefixes = {}
if args.lang then
table.insert(prefixes, args.lang)
end
if args.sister then
table.insert(prefixes, args.sister)
end
linkBody = table.concat(prefixes, ':')
if #linkBody ~= 0 then
linkBody = ':' .. linkBody
end
if mw.ustring.sub(name, 1, 1) ~= ':' then
linkBody = linkBody .. ':'
end
if not global then
linkBody = linkBody .. 'Template:'
end
linkBody = linkBody .. name
titleObject = mw.title.new(linkBody)
local noLink = flags.noLink or currentTitle == titleObject
local takeBracketsInLink = not noLink and
mw.ustring.len(name) == 1 and
not flags.black and
not flags.subst and
not flags.podst
if not noLink then
if not flags.noRedirect or (
flags.noRedirect and
not args.lang and
not args.sister and
not titleObject.exists
) then
linkBegin = '[['
linkEnd = ']]'
linkDivider = '|'
else
linkBegin = '['
linkEnd = ']'
linkDivider = ' '
linkBody = titleObject:fullUrl('redirect=no')
end
end
local text = ''
if flags.nav and currentTitle == titleObject then
text = text .. '\'\'\''
end
if not flags.black then
text = text .. '<span class="wp-templatelink">'
end
text = text .. '{'
if not takeBracketsInLink then
text = text .. '{'
end
if flags.subst then
text = text .. 'subst:'
elseif flags.podst then
text = text .. 'подст:'
end
if not flags.black then
text = text .. '</span>'
end
text = text .. '<span data-navboxnavigation-link="0">'
local commentedLabel
if args.comment then
-- https://phabricator.wikimedia.org/T200704
-- commentedLabel = mw.getCurrentFrame():expandTemplate({title = 'comment', args = {(args.text or name), args.comment}})
commentedLabel = '<span class="commentedText" title="' .. args.comment .. '" style="border-bottom: 1px dotted; cursor: help;">' ..
(args.text or name) ..
'</span>'
end
local label = (commentedLabel or args.text or name)
if not noLink then
if flags.noRedirect then
text = text .. '<span class="plainlinks">'
end
text = text .. linkBegin .. linkBody .. linkDivider
if not noLink and takeBracketsInLink then
text = text .. '<span class="wp-templatelink">{</span>'
end
text = text .. label
if not noLink and takeBracketsInLink then
text = text .. '<span class="wp-templatelink">}</span>'
end
text = text .. linkEnd
if flags.noRedirect then
text = text .. '</span>'
end
else
text = text .. label
end
text = text .. '</span>'
if not flags.black then
text = text .. '<span class="wp-templatelink">'
end
text = text .. '}'
if not takeBracketsInLink then
text = text .. '}'
end
if not flags.black then
text = text .. '</span>'
end
if flags.nav and currentTitle == titleObject then
text = text .. '\'\'\''
end
return text
end
function addParams(args, params)
local text, equals_pos, param, value = '', 0, '', ''
function addPipe()
if params.spaced then
text = text .. ' '
end
text = text .. '<span'
if not params.black then
text = text .. ' class="wp-templatelink"'
end
if not params.spaced then
text = text .. ' style="margin:0 2px;"'
end
text = text .. '>|</span>'
end
for k, v in pairs(args) do
if type(k) == 'number' then -- Неименованные параметры
equals_pos = v:find('=')
if equals_pos and v:find('{{=}}') == equals_pos - 2 then
equals_pos = nil
end
if equals_pos then -- Содержащие «=» преобразуем в именованные
param = v:sub(1, equals_pos - 1)
value = v:sub(equals_pos + 1)
addPipe()
text = text .. param .. '=' .. value
else -- Истинно неименованные
addPipe()
text = text .. v
end
elseif not k:find('^_') then -- Именованные параметры, исключая модификаторы внешнего вида
addPipe()
text = text .. k .. '=' .. v
end
end
return text
end
p.withParams = makeInvokeFunc('_withParams')
function p._withParams(args)
local name = args[1]
table.remove(args, 1)
-- Вещи типа «=» в первом параметре
if not name then
for k, v in pairs(args) do
if not k:find('^_') then
name = k .. '=' .. v
args[k] = nil
break
end
end
end
local optpText
if name then
local spanOffset = mw.ustring.find(name, '<span') -- След использования шаблона optp
if spanOffset then
optpText = mw.ustring.sub(name, spanOffset)
name = mw.ustring.sub(name, 1, spanOffset - 1)
end
end
local yesno = require('Module:Yesno')
local nobr = yesno(args._nobr, false)
local tag = args._tag or 'span'
local style = args._style
local spaced = yesno(args._spaced, false)
local subst = yesno(args._s, false)
local podst = yesno(args['_п'], false)
local global = yesno(args._g, false) or name and mw.ustring.sub(name, 1, 1) == ':'
local lang = args._lang
local sister = args._sister
local nav = yesno(args._nav, false)
local ucFirst = yesno(args._u, false)
local black = yesno(args._b, false) or tag ~= 'span'
local noLink = yesno(args._nolink or args._nl, false) or not yesno(args._link, false)
local textInPlaceOfName = args._text
local comment = args._comment
local noRedirect = yesno(args._noredir, false)
local prefix = args._prefix
local postfix = args._postfix
if textInPlaceOfName == '' then
textInPlaceOfName = nil
end
if comment == '' then
comment = nil
end
if lang == '' then
lang = nil
end
if sister == '' then
sister = nil
end
if name then
local trimmedName = mw.text.trim(name)
if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'subst:' then
subst = true
name = mw.ustring.sub(trimmedName, 7)
end
if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'подст:' then
podst = true
name = mw.ustring.sub(trimmedName, 7)
end
end
local currentTitle = mw.title.getCurrentTitle()
-- При опущенном первом параметре берём имя шаблона из названия страницы
if name == '' or not name then
local currentTitleRoot = currentTitle.rootText
if not ucFirst and
((ru:uc(currentTitleRoot) ~= currentTitleRoot and
-- Книга:Литературное наследство, TranslateDate
not mw.ustring.match(currentTitleRoot, '^[А-Яа-яA-Za-z]+:?[А-ЯA-Z]')
) or
#currentTitleRoot == 1
)
then
name = ru:lcfirst(currentTitleRoot)
else
name = currentTitleRoot
end
end
-- Начинаем собирать код
local linkBody, titleObject, linkBegin, linkDivider, linkEnd
local prefixes = {}
if lang then
table.insert(prefixes, lang)
end
if sister then
table.insert(prefixes, sister)
end
linkBody = table.concat(prefixes, ':')
if #linkBody ~= 0 then
linkBody = ':' .. linkBody
end
if mw.ustring.sub(name, 1, 1) ~= ':' then
linkBody = linkBody .. ':'
end
if not global then
linkBody = linkBody .. 'Template:'
end
linkBody = linkBody .. name
titleObject = mw.title.new(linkBody)
local noLink = noLink or currentTitle == titleObject
local takeBracketsInLink = not noLink and
mw.ustring.len(name) == 1 and
not black and
not subst and
not podst
if not noLink then
if not noRedirect or (
noRedirect and
not lang and
not sister and
not titleObject.exists
) then
linkBegin = '[['
linkEnd = ']]'
linkDivider = '|'
else
linkBegin = '['
linkEnd = ']'
linkDivider = ' '
linkBody = titleObject:fullUrl('redirect=no')
end
end
local text = ''
if tag then
text = text .. '<' .. tag .. ' class="templateCallCode'
if nobr then
text = text .. ' nowrap'
end
text = text .. '"'
if style then
text = text .. ' style="' .. style .. '"'
end
text = text .. '>'
end
if prefix then
text = text .. prefix
end
if not black then
text = text .. '<span class="wp-templatelink">'
end
text = text .. '{{'
if subst then
text = text .. 'subst:'
elseif podst then
text = text .. 'подст:'
end
if not black then
text = text .. '</span>'
end
if nav and currentTitle == titleObject then
text = text .. '\'\'\''
end
local commentedLabel
if comment then
-- https://phabricator.wikimedia.org/T200704
-- commentedLabel = mw.getCurrentFrame():expandTemplate({title = 'comment', args = {(text or name), comment}})
commentedLabel = '<span class="commentedText" title="' .. comment .. '" style="border-bottom: 1px dotted; cursor: help;">' ..
(textInPlaceOfName or name) ..
'</span>'
end
local label = (commentedLabel or textInPlaceOfName or name)
if not noLink then
if noRedirect then
text = text .. '<span class="plainlinks">'
end
text = text .. linkBegin .. linkBody .. linkDivider .. label .. linkEnd
if noRedirect then
text = text .. '</span>'
end
else
text = text .. label
end
if nav and currentTitle == titleObject then
text = text .. '\'\'\''
end
if optpText then
text = text .. optpText
end
text = text .. addParams(args, {
spaced = spaced,
black = black,
})
if spaced then
text = text .. ' '
end
if not black then
text = text .. '<span class="wp-templatelink">'
end
text = text .. '}}'
if not black then
text = text .. '</span>'
end
if postfix then
text = text .. postfix
end
if tag then
text = text .. '</' .. tag .. '>'
end
return text
end
p.onlyParams = makeInvokeFunc('_onlyParams')
function p._onlyParams(args)
local span = mw.html.create('span')
span:css( 'color', mw.getCurrentFrame():expandTemplate({ title = 'optp/color' }) )
local yesno = require('Module:Yesno')
span:wikitext(addParams(args, {
spaced = yesno(args._spaced, false),
black = true,
}))
return tostring(span)
end
return p
0b9f3af403c5d8136788ce6aae12a9b96ee4fe52
Модуль:Yesno
828
127
573
2021-07-29T21:08:23Z
ruwiki>WerySkok
0
1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии.
Scribunto
text/plain
-- Function allowing for consistent treatment of boolean-like wikitext input.
-- It works similarly to the template {{yesno}}.
return function (val, default)
-- If your wiki uses non-ascii characters for any of "yes", "no", etc., you
-- should replace "val:lower()" with "mw.ustring.lower(val)" in the
-- following line.
val = type(val) == 'string' and val:lower() or val
if val == nil then
return nil
elseif val == true
or val == 'yes'
or val == 'y'
or val == 'true'
or val == 't'
or val == 'да'
or val == 'д'
or val == '+'
or tonumber(val) == 1
then
return true
elseif val == false
or val == 'no'
or val == 'n'
or val == 'false'
or val == 'f'
or val == 'нет'
or val == 'н'
or val == '-'
or tonumber(val) == 0
then
return false
else
return default
end
end
2aa6facc3ee47eb7582d828363d3c1ddc64593d2
Модуль:Transclude
828
144
657
330
2021-07-29T21:08:23Z
ruwiki>WerySkok
0
1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии.
Scribunto
text/plain
local p={}
-- Вызывает внутренний шаблон с аргументами объемлющего шаблона
function p.call(frame)
local template = frame.args[1]
local args = frame:getParent().args
return frame:expandTemplate{ title=template, args=args }
end
-- Общая реализация для forall и call
local function forallImpl(args, separator, conjunction, func)
-- нумерованные ключи из args
local keys = {}
-- перебор в произвольном порядке, даже для нумерованных ключей
for key, value in pairs(args) do
if type(key) == 'number' and value and value ~= '' then
table.insert(keys, key)
end
end
table.sort(keys)
local results = {}
for _, key in ipairs(keys) do
local value = func(args[key])
table.insert(results, value)
end
return mw.text.listToText(results, separator, conjunction)
end
-- Вызывает внутренний шаблон, передавая ему нумерованные параметры объемлющего шаблона по-одному
function p.forall(frame)
local template = frame.args[1]
local separator = frame.args.separator or ''
local conjunction = frame.args.conjunction or separator
local args = frame:getParent().args
local func = function(value)
return frame:expandTemplate{ title = template, args = {value} } -- или другой frame?
end
return forallImpl(args, separator, conjunction, func)
end
-- Берёт нумерованные аргументы объемлющего шаблона и склеивает их в единую строку
function p.join(frame)
local separator = frame.args[1] or ''
local conjunction = frame.args[2] or separator
local args = frame:getParent().args
local func = function(value)
return value
end
return forallImpl(args, separator, conjunction, func)
end
-- Служебная функция: удаляет дубликаты из отсортированного массива с нумерованными индексами
local function deleteDuplicates(args)
local res = {}
for key, value in pairs(args) do
if args[key+1] ~= value then
table.insert(res, value)
end
end
return res
end
-- Вызывает внутренний шаблон несколько раз, передавая в него блоки аргументов объемлющего шаблона
function p.npc(frame)
local args = frame:getParent().args
local templateFrame = frame:getParent()
local template = frame.args[1]
-- определение, блоки аргументов с какими номерами нужны:
-- если в объемлющем шаблоне есть "параметр12" и в вызове модуля есть "параметр", то вызывается 12-й блок
local nums = {}
for key, _ in pairs(args) do
local main, num = string.match(key, '^(.-)%s*(%d*)$')
num = tonumber(num)
-- учитывать "параметр12", только если задано "параметр"
if num and frame.args[main] then
table.insert(nums, num)
end
end
table.sort(nums)
nums = deleteDuplicates(nums)
-- проходить по нужным номерам блоков по возрастанию и однократно
-- подставлять в шаблон:
-- 1. общие аргументы данного модуля
-- 2. аргументы объемлющего шаблона вида "параметр12" как "параметр" в 12-й блок
local results = {}
for _, blockNum in ipairs(nums) do
-- общие аргументы модуля, которые передаются в каждый блок
local blockArgs = mw.clone(frame.args)
-- metatable ломает expandTemplate
setmetatable(blockArgs, nil)
for key, value in pairs(args) do
local main, num = string.match(key, '^(.-)%s*(%d*)$')
num = tonumber(num)
-- передавать "параметр12" как "параметр" в 12-й блок, только если есть "параметр" в вызове модуля
if blockNum == num and frame.args[main] then
blockArgs[main] = value
end
end
local blockText = templateFrame:expandTemplate{ title=template; args=blockArgs }
table.insert(results, blockText)
end
return table.concat(results)
end
-- Действует аналогично forall по числовой переменной, изменяющейся (по умолчанию, от 1) до f.args[2].
function p.cycle(f)
local tf,ac,op=f:getParent(), {}, f.args.output or 'inline';
local sep='';
if op == 'newline' then
sep='\n';
end
for p,k in pairs(f.args) do
if type(p)=='number' then
if p>2 then ac[p-1]=k end
else ac[p]=k
end
end
local s,fh = f.args[2]:match('^%s*(%-?%d+)%s*%.%.') or 1,
f.args[2]:match('%.%.%s*(%S.*)%s*$') or f.args[2] or '';
fh=tonumber(fh) or fh:match('^%s*(.-)%s*$');
s=tonumber(s);
local acr={};
if not s then error('Начало цикла «'..s..'» — не число') end
local function dc(order)
local r=tf:expandTemplate{ title=f.args[1]; args={s,unpack(ac)} }
if order == 'desc' then
s=s-1;
else
s=s+1;
end
if r~='' then table.insert(acr,r); return r end
end
if type(fh)=='number' then
if fh > s then
while s<=fh do dc('asc') end
else
while s>=fh do dc('desc') end
end
elseif fh~='' then
while tf:expandTemplate{ title=fh; args={s,unpack(ac)} } do dc('asc') end
else
while dc('asc') do end
end
return table.concat(acr, sep)
end
return p
c17cfab4cebc23157f5ab8d18c7e4f5c273bfa59
Модуль:Якорь
828
237
575
2021-07-29T21:08:24Z
ruwiki>WerySkok
0
1 версия импортирована: Импорт Инфобокса из Русскоязычной википедии.
Scribunto
text/plain
local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')
local compressSparseArray = require('Module:TableTools').compressSparseArray
local p = {}
local function add_anchor(anchor, text, visible)
local result = mw.html.create('span')
:attr('id', anchor)
:wikitext(text)
if visible then
result:addClass('highlight-target')
end
return tostring(result)
end
local function unpack(...)
local frame = ...
local args
if type(frame.args) == 'table' then
args = getArgs(frame)
elseif type(frame) == 'table' then
args = frame
else
args = {...}
end
return args
end
function p.main(...)
local args = unpack(...)
local anchors = compressSparseArray(args)
local text
local visible = yesno(args.visible or args.v)
if visible then
text = args.text or args['текст'] or args[1]
end
local result = text
for i, v in ipairs(anchors) do
result = add_anchor(anchors[i], result, visible)
--[[
создание старого вида якорей для совместимости,
см. Обсуждение шаблона:Якорь#Новые html5 ссылки и старые
]]
local encoded_anchor = mw.uri.encode(anchors[i], 'WIKI'):gsub('%%', '.')
if anchors[i] ~= encoded_anchor then
result = add_anchor(encoded_anchor, result, visible)
end
end
return result
end
return p
2cd9bcc85d4af30c1681bbadfc7d10c60a63e5f2
Шаблон:Указание авторства русскоязычной Википедии
10
235
559
2021-07-30T08:31:06Z
ruwiki>WerySkok
0
Новая страница: «<includeonly>{| style="border: 1px solid #e0e0e0; background-color: #f8f8f8; color:black; margin: 5px auto; width: 60%;" |- | style="padding: 3px 10px;" | File:...»
wikitext
text/x-wiki
<includeonly>{| style="border: 1px solid #e0e0e0; background-color: #f8f8f8; color:black; margin: 5px auto; width: 60%;"
|-
| style="padding: 3px 10px;" | [[File:Wikipedia-logo-v2.svg|30px|Wikipedia logo]]
| style="font-size: 90%; padding: 3px;" |{{Namespace detect|template=Данный шаблон|other=Данная страница}} использует материал из {{Namespace detect|template=шаблона|other=страницы}} [[w:ru:{{{1|{{FULLPAGENAME}}}}}|{{{1|{{FULLPAGENAME}}}}}]] с русскоязычной Википедии, который выпущен под [[w:ru:Википедия:Текст лицензии Creative Commons Attribution-ShareAlike 3.0 Unported|лицензией Creative Commons Attribution-ShareAlike 3.0 Unported]] ([https://ru.wikipedia.org/w/index.php?title={{urlencode:{{{1|{{FULLPAGENAME}}}}}}}&action=history посмотреть авторов]).
|}
[[Категория:{{Namespace detect|main=Статьи|category=Категории|file=Файлы|template=Шаблоны|other=Страницы}} из русскоязычной Википедии]]</includeonly>
<noinclude>
{{Doc}}
[[Категория:Шаблоны с указанием авторства]]
{{Указание авторства англоязычной Википедии|Template:En-WP attribution notice}}
</noinclude>
f6a3b5534c9f0bd71170f01c372f6d47cc03c302
Шаблон:Документировать
10
18
635
2021-07-30T08:33:09Z
ruwiki>WerySkok
0
wikitext
text/x-wiki
{{ombox
|type = content
|text = '''Этому {{#ifeq: {{NAMESPACE}} | Модуль | модулю | шаблону }} не хватает документации.'''
|text-small = Вы можете помочь проекту, {{big|'''[[{{SUBJECTSPACE}}:{{PAGENAME:{{{1|{{SUBJECTPAGENAME}}/doc}}}}}|сделав описание {{#ifeq: {{NAMESPACE}} | Модуль | модуля | шаблона }}]]'''}}: что он делает, как его использовать, какие параметры он принимает, в какие категории добавляет. Это поможет другим использовать его.
* Не забывайте про категории ({{#ifeq: {{NAMESPACE}} | Модуль || на странице /doc  }}их нужно оборачивать в {{tag|includeonly}}) и [[вп:ВП:Интервики|интервики]].
* Некоторые советы по оформлению есть на Википедии на странице проекта «[[вп:Проект:Технические работы/Шаблоны/Документирование|Документирование шаблонов]]».
}}<includeonly>{{#if: {{{nocat|}}}{{#ifeq: {{PAGENAME}} | {{SUBPAGENAME}} || {{#ifeq: {{SUBPAGENAME}} | песочница | nocat }} }} ||
{{#switch: {{NAMESPACE}}
| {{ns:10}} = [[Категория:Шаблоны:Недокументированные]]
| {{ns:828}} = {{#ifeq:{{ROOTPAGENAME}}|Песочница||[[Категория:Модули:Недокументированные]]}}
}} }}</includeonly><noinclude>
{{doc-inline}}
Данное сообщение появляется при отсутствующей странице документации, включаемой шаблоном {{t|doc}}.
{{doc-end}}
{{Указание авторства русскоязычной Википедии}}
[[Категория:Шаблоны:Предупреждения]]
[[Категория:Шаблоны:Для документирования шаблонов]]
</noinclude>
2de13a375cc1c8a836791cda48d72fe9d8b3a1f4
Модуль:Infobox
828
211
470
2021-08-16T20:12:46Z
ruwiki>Putnik
0
scope="colgroup" для заголовков
Scribunto
text/plain
local p = {};
local yesno = require('Module:Yesno')
local function _renderLine( frame, args, i )
if args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] == '-' then
return ''
elseif args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] ~= '' then
local style = ( args[ 'стиль_заголовков' ] or '' ) .. ( args[ 'стиль_заголовка' .. i ] or '' );
local class = ( args[ 'класс' .. i ] or '' );
return '\n<tr>\n<th colspan="2" scope="colgroup" class="infobox-header ' .. class .. '" style="' .. style .. '">' ..
args[ 'заголовок' .. i ] ..
'</th>\n</tr>';
end
if args[ 'блок' .. i ] and args[ 'блок' .. i ] ~= '' then
return args[ 'блок' .. i ];
end
local text = args[ 'текст' .. i ] or '';
if args[ 'викиданные' .. i ] and args[ 'викиданные' .. i ] ~= '' then
text = frame:expandTemplate{ title = 'Wikidata', args = {
args[ 'викиданные' .. i ],
text,
from = args[ 'from' ] or ''
} };
end
if text ~= '' then
local label = args[ 'метка' .. i ] or '';
local class = args[ 'класс' .. i ] or '';
if string.find(class, 'noplainlist') == nil and string.find(class, 'nofirstlevel') == nil then
class = class .. ' plainlist';
end
if class ~= '' then
class = ' class="' .. class .. '"';
end
local style = ( args[ 'стиль_текстов' ] or '' ) .. ( args[ 'стиль_текста' ] or '' ) .. ( args[ 'стиль_текста' .. i ] or '' );
if label == '' then
style = 'text-align:center;' .. style;
end
if style ~= '' then
style = ' style="' .. style .. '"';
end
if label ~= '' then
local labelClass = args[ 'класс_меток' ] or '';
if string.find(labelClass, 'noplainlist') == nil and string.find(labelClass, 'nofirstlevel') == nil then
labelClass = labelClass .. ' plainlist';
end
if labelClass ~= '' then
labelClass = ' class="' .. labelClass .. '"';
end
local labelStyle = ( args[ 'стиль_меток' ] or '' ) .. ( args[ 'стиль_метки' .. i ] or '' );
if labelStyle ~= '' then
labelStyle = ' style="' .. labelStyle .. '"';
end
return '\n<tr>\n<th scope="row"' .. labelClass .. labelStyle .. '>' .. label .. '</th>' ..
'\n<td' .. class .. style .. '>\n' .. text .. '</td>\n</tr>';
end
return '\n<tr>\n<td colspan="2"' .. class .. style .. '>\n' .. text .. '</td>\n</tr>';
end
return '';
end
local function maxNumber ( args )
local maxNumber = 0
for argName, _ in pairs(args) do
local argNumber = mw.ustring.match(argName, '^[^0-9]+([0-9]+)$')
if argNumber and tonumber(argNumber) > maxNumber then
maxNumber = tonumber(argNumber)
end
end
return maxNumber
end
function p.renderLine( frame )
local args = frame:getParent().args;
return _renderLine(frame, args, '')
end
function p.renderLines( frame )
local args = frame:getParent().args;
local res = ''
local header, text = '', ''
local autoHeaders = yesno(args [ 'автозаголовки' ] or 'false', false)
for i = 1, maxNumber(args) do
if args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] ~= '' then
if text ~= '' or not autoHeaders then
res = res .. header .. text
end
header, text = _renderLine(frame, args, i), ''
else
text = text .. _renderLine(frame, args, i)
end
end
if text ~= '' or not autoHeaders then
res = res .. header .. text
end
return res
end
return p;
c830c997bd3d15923f347277e3b0ae71b7ba917e
637
470
2021-08-30T20:11:48Z
ruwiki>WerySkok
0
1 версия импортирована
Scribunto
text/plain
local p = {};
local yesno = require('Module:Yesno')
local function _renderLine( frame, args, i )
if args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] == '-' then
return ''
elseif args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] ~= '' then
local style = ( args[ 'стиль_заголовков' ] or '' ) .. ( args[ 'стиль_заголовка' .. i ] or '' );
local class = ( args[ 'класс' .. i ] or '' );
return '\n<tr>\n<th colspan="2" scope="colgroup" class="infobox-header ' .. class .. '" style="' .. style .. '">' ..
args[ 'заголовок' .. i ] ..
'</th>\n</tr>';
end
if args[ 'блок' .. i ] and args[ 'блок' .. i ] ~= '' then
return args[ 'блок' .. i ];
end
local text = args[ 'текст' .. i ] or '';
if args[ 'викиданные' .. i ] and args[ 'викиданные' .. i ] ~= '' then
text = frame:expandTemplate{ title = 'Wikidata', args = {
args[ 'викиданные' .. i ],
text,
from = args[ 'from' ] or ''
} };
end
if text ~= '' then
local label = args[ 'метка' .. i ] or '';
local class = args[ 'класс' .. i ] or '';
if string.find(class, 'noplainlist') == nil and string.find(class, 'nofirstlevel') == nil then
class = class .. ' plainlist';
end
if class ~= '' then
class = ' class="' .. class .. '"';
end
local style = ( args[ 'стиль_текстов' ] or '' ) .. ( args[ 'стиль_текста' ] or '' ) .. ( args[ 'стиль_текста' .. i ] or '' );
if label == '' then
style = 'text-align:center;' .. style;
end
if style ~= '' then
style = ' style="' .. style .. '"';
end
if label ~= '' then
local labelClass = args[ 'класс_меток' ] or '';
if string.find(labelClass, 'noplainlist') == nil and string.find(labelClass, 'nofirstlevel') == nil then
labelClass = labelClass .. ' plainlist';
end
if labelClass ~= '' then
labelClass = ' class="' .. labelClass .. '"';
end
local labelStyle = ( args[ 'стиль_меток' ] or '' ) .. ( args[ 'стиль_метки' .. i ] or '' );
if labelStyle ~= '' then
labelStyle = ' style="' .. labelStyle .. '"';
end
return '\n<tr>\n<th scope="row"' .. labelClass .. labelStyle .. '>' .. label .. '</th>' ..
'\n<td' .. class .. style .. '>\n' .. text .. '</td>\n</tr>';
end
return '\n<tr>\n<td colspan="2"' .. class .. style .. '>\n' .. text .. '</td>\n</tr>';
end
return '';
end
local function maxNumber ( args )
local maxNumber = 0
for argName, _ in pairs(args) do
local argNumber = mw.ustring.match(argName, '^[^0-9]+([0-9]+)$')
if argNumber and tonumber(argNumber) > maxNumber then
maxNumber = tonumber(argNumber)
end
end
return maxNumber
end
function p.renderLine( frame )
local args = frame:getParent().args;
return _renderLine(frame, args, '')
end
function p.renderLines( frame )
local args = frame:getParent().args;
local res = ''
local header, text = '', ''
local autoHeaders = yesno(args [ 'автозаголовки' ] or 'false', false)
for i = 1, maxNumber(args) do
if args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] ~= '' then
if text ~= '' or not autoHeaders then
res = res .. header .. text
end
header, text = _renderLine(frame, args, i), ''
else
text = text .. _renderLine(frame, args, i)
end
end
if text ~= '' or not autoHeaders then
res = res .. header .. text
end
return res
end
return p;
c830c997bd3d15923f347277e3b0ae71b7ba917e
Шаблон:Карточка/doc
10
226
645
2021-08-30T19:19:07Z
ruwiki>WerySkok
0
wikitext
text/x-wiki
{{docpage}}
{{OnLua|Infobox|renderLines}}
Это меташаблон для создания [[вп:Википедия:Шаблоны-карточки|шаблонов-карточек]].
== Параметры ==
=== Служебные ===
; имя: Имя шаблона, необходимое для корректной работы служебных инструментов на всех страницах, где используется шаблон. Для простоты можно использовать <code><nowiki>{{subst:PAGENAME}}</nowiki></code>.
; автозаголовки: Указание «да» приводит к автоматическому скрытию заголовков, после которых, вплоть до следующего заголовка, все поля пусты. Возможно использовать фиктивные заголовки «-» для прерывания области скрытия. Будет работать некорректно, если требуется указать два заголовка подряд — например, при использовании многоуровневых заголовков. В этом случае рекомендуется явно указать «нет» на случай смены значения по умолчанию с «нет» на «да».
; from: Указывается элемент Викиданных, из которого берётся информация.
=== Основные ===
; вверху: Текст, отображаемый вверху таблицы. Обычно это название предмета статьи.
; вверху2: Дополнительный текст, отображаемый вверху таблицы. Обычно используется для оригинального названия.
; вверху3: Дополнительный текст, отображаемый вверху таблицы.
; изображение: Изображение, которое будет отображено под основным заголовком в правой части таблицы (правее заголовков/списков). Параметр ''изображение'' допускает стандартный викикод для отображения. Для разных типов параметра можно использовать {{tl|Форматирование изображения}}. Обычно предпочтительнее использовать код <code><nowiki>{{Карточка/изображение|{{{изображение|}}}|size={{{ширина|}}}|caption={{{описание изображения|}}}}}</nowiki></code>.
; подпись: Подпись под изображением. Отображается только в том случае, если задано изображение. При использовании {{tlp|Карточка/изображение}} не заполняется.
; изображение2: Дополнительное изображение.
; изображение3: Дополнительное изображение.
; заголовок<sub>n</sub>: Используется для создания заголовков в ряду. Этот и следующие 2 параметра работают при n≥1.
; метка<sub>n</sub>: Используется для подписи текста
; текст<sub>n</sub>: Используется для принятия параметров в специализированных шаблонах-карточках.
; блок<sub>n</sub>: Технический параметр, используется для вставки блоков, заключённых в <tr&rt;, таких как {{t|карточка/блок}}.
; внизу
; внизу<sub>n</sub>: Ячейка во всю ширину таблицы, располагающаяся внизу тела шаблона (то есть под заголовками/метками и текстом).
=== Стили ===
; стиль_тела: Применяется ко всей карточке, обычно используется для указания её ширины, например, <code>width:23em;</code>
; стиль_вверху: Применяется к полю «вверху», например, для указания цвета фона или изменения размера шрифта: <code>font-size:medium;</code>
; стиль_вверху<sub>n</sub>: Используется для изменения стиля дополнительного текста вверху таблицы, например, чтобы убрать курсивное начертание: <code>font-style:normal;</code>
; стиль_изображения: Применяется к ячейке, в которой располагается изображение и его описание
; стиль_изображения<sub>n</sub>: Применяется к ячейке, в которой располагается дополнительное изображение
; стиль_подписи: Применяется к подписи изображения
; стиль_заголовков: С помощью этого стиля можно настроить отображение заголовков, в частности, указать цвет фона: <code>background: #a3eea3;</code>
; стиль_заголовка<sub>n</sub>: Применяется к конкретному заголовку в строке n
; стиль_меток: Применяется к меткам
; стиль_метки<sub>n</sub>: Применяется к конкретной метке в строке n
; стиль_текста: Применяется к тексту
; стиль_текста<sub>n</sub>: Применяется к конкретному тексту в строке n
; стиль_внизу: Эти стили применяются не только в первому ''внизу'', но и ко всем остальным — в отличие от ''стиль_вверху''.
; стиль_внизу<sub>n</sub>: CSS-стили, которые должны быть применены к нижним (указанными параметрами ''внизу'' и ''внизу<sub>n</sub>'') ячейкам.
== Возможности ==
=== Сдвоенные ячейки ===
Если для параметра <code>текст<sub>n</sub></code> значение <code>метка<sub>n</sub></code> не определено, то <code>текст<sub>n</sub></code> автоматически расширяется до 2 ячеек. Для выравнивания по левой стороне можно использовать следующий код:
<pre><nowiki>
|текст2 = {{{параметр|}}}
|стиль_текста2 = text-align:left;
</nowiki></pre>
=== Необязательные ячейки ===
Ряд с меткой, но без текста не будет отображён. Это позволяет легко создавать необязательные параметры в специализированных шаблонах-карточках. Для создания опциональной ячейки используйте параметр следующим образом:
<pre><nowiki>
|метка5 = Население
|текст5 = {{{население|}}}
</nowiki></pre>
Таким образом, если параметр <code>население</code> не будет определён, строка «Население» не будет отображена.
=== Необязательные заголовки ===
Таким же образом можно организовать необязательные заголовки. Следующий пример будет выводить заголовок «Структура», если параметры <code>содержимое</code> и <code>размещение</code> определены:
<pre><nowiki>
|заголовок5 = {{#if:{{{содержимое|}}}{{{размещение|}}}|Структура}}
|метка6 = Содержимое
|текст6 = {{{содержимое|}}}
|метка7 = Размещение
|текст7 = {{{размещение|}}}
</nowiki></pre>
Если есть заголовокN, то текстN и меткаN игнорируются. Если нет заданного заголовкаN, то показываются текстN и меткаN.
{|
|-
|<pre><nowiki>
|заголовок1 = {{{заголовок1|}}}
|метка1 = {{{метка1|}}}
|текст1 = {{{текст1|}}}
</nowiki></pre>
|}
{|
|-
|<pre><nowiki>
|заголовок1 = заголовок_текст
|метка1 = метка_текст
|текст1 = текст_текст
</nowiki></pre>
|
{| class="wikitable"
|-
! заголовок_текст
|}
|<pre><nowiki>
|заголовок1 =
|метка1 = метка_текст
|текст1 = текст_текст
</nowiki></pre>
|
{| class="wikitable"
|-
| метка_текст|| текст_текст
|}
|}
=== Оформление параметров ===
Для оформления параметра можно использовать [[w:ru:Википедия:Функции парсера##if|функцию парсера «#if»]]. Например, следующие строки добавят к параметру <code>текст6</code> подпись кг, если этот параметр определён:
<pre><nowiki>
|метка6 = Масса
|текст6 = {{#if:{{{масса|}}} |{{{масса}}} кг}}
</nowiki></pre>
А расстановку ссылок на страницы можно организовать с помощью [[w:ru:Википедия:Функции парсера##switch:|«#switch»]], например:
<pre><nowiki>
|метка6 = Раса
|текст6 = {{#switch:{{{раса|}}}
|Европеоиды = [[Европеоидная раса|Европеоиды]]
|Негроиды = [[Негроидная раса|Негроиды]]
|Монголоиды = [[Монголоидная раса|Монголоиды]]
|{{{раса|}}}
}}
</nowiki></pre>
== Пустой шаблон ==
<pre>
{{Карточка
|имя = {{subst:PAGENAME}}
|автозаголовки = да
|стиль_вверху =
|стиль_заголовков =
|стиль_внизу =
|вверху =
|вверху2 =
|изображение =
|заголовок1 =
|метка2 =
|текст2 =
|метка3 =
|текст3 =
|метка4 =
|текст4 =
|метка5 =
|текст5 =
|метка6 =
|текст6 =
|метка7 =
|текст7 =
|метка8 =
|текст8 =
|метка9 =
|текст9 =
|метка10 =
|текст10 =
...
|меткаN =
|текстN =
|внизу =
}}<noinclude>
{{doc}}
</noinclude></pre>
{{скрытый|Заголовок=11-20|Содержание=<pre>
|метка11 =
|текст11 =
|метка12 =
|текст12 =
|метка13 =
|текст13 =
|метка14 =
|текст14 =
|метка15 =
|текст15 =
|метка16 =
|текст16 =
|метка17 =
|текст17 =
|метка18 =
|текст18 =
|метка19 =
|текст19 =
|метка20 =
|текст20 =
</pre>}}
{{скрытый||Заголовок=21-30|Содержание=<pre>
|метка21 =
|текст21 =
|метка22 =
|текст22 =
|метка23 =
|текст23 =
|метка24 =
|текст24 =
|метка25 =
|текст25 =
|метка26 =
|текст26 =
|метка27 =
|текст27 =
|метка28 =
|текст28 =
|метка29 =
|текст29 =
|метка30 =
|текст30 =
</pre>}}
{{скрытый||Заголовок=31-40|Содержание=<pre>
|метка31 =
|текст31 =
|метка32 =
|текст32 =
|метка33 =
|текст33 =
|метка34 =
|текст34 =
|метка35 =
|текст35 =
|метка36 =
|текст36 =
|метка37 =
|текст37 =
|метка38 =
|текст38 =
|метка39 =
|текст39 =
|метка40 =
|текст40 =
</pre>}}
{{скрытый||Заголовок=41-50|Содержание=<pre>
|метка41 =
|текст41 =
|метка42 =
|текст42 =
|метка43 =
|текст43 =
|метка44 =
|текст44 =
|метка45 =
|текст45 =
|метка46 =
|текст46 =
|метка47 =
|текст47 =
|метка48 =
|текст48 =
|метка49 =
|текст49 =
|метка50 =
|текст50 =
</pre>}}
{{скрытый||Заголовок=51-60|Содержание=<pre>
|метка51 =
|текст51 =
|метка52 =
|текст52 =
|метка53 =
|текст53 =
|метка54 =
|текст54 =
|метка55 =
|текст55 =
|метка56 =
|текст56 =
|метка57 =
|текст57 =
|метка58 =
|текст58 =
|метка59 =
|текст59 =
|метка60 =
|текст60 =
</pre>}}
== Примерный шаблон для карточки персоны ==
<pre>{{Карточка
|имя = {{subst:PAGENAME}}
|автозаголовки = да
|стиль_вверху =
|стиль_заголовков =
|стиль_внизу =
|вверху = {{карточка/имя|{{{имя|}}}}}
|вверху2 = {{карточка/оригинал имени|{{{оригинал имени|}}}}}
|изображение = {{Карточка/изображение|{{{фото|}}}|caption={{{описание изображения|}}}|size={{{ширина|}}}}}
|метка1 = Имя при рождении
|текст1 = {{{имя при рождении|}}}
|метка2 = Дата рождения
|текст2 = {{{дата рождения|}}}
|метка3 = Место рождения
|текст3 = {{{место рождения|}}}
|метка4 = Дата смерти
|текст4 = {{{дата смерти|}}}
|метка5 = Место смерти
|текст5 = {{{место смерти|}}}
|метка6 = Гражданство
|текст6 = {{{гражданство|}}}
|метка7 = Сценические имена / Прозвище
|текст7 = {{{прозвище|}}}
|заголовок8 = {{{сайт|}}}
}}</pre>
== См. также ==
* [[вп:Википедия:Шаблоны-карточки|Википедия:Шаблоны-карточки]]
* {{t|Универсальная карточка}}
* {{t|Навигационная таблица}} — для создания горизонтальных навигационных таблиц (предпочтительный вертикальных, иногда делаемых на карточке)
* {{t|Карточка/блок}} — для создания кусков, вставляемых в разные карточки
* [[:Категория:Шаблоны:Подстраницы шаблона Карточка|Подстраницы шаблона Карточка]]
* [[w:ru:Участник:Jack who built the house/alignTemplateParameters.js|Участник:Jack who built the house/alignTemplateParameters.js]]
<includeonly>
[[Категория:Шаблоны-карточки|*]]
[[Категория:Шаблоны:Мета-шаблоны]]
</includeonly>
ae10a532e2d2584c783d40f5a375419a0946b865
Шаблон:Ifsubst
10
238
577
2021-08-30T19:34:36Z
ruwiki>WerySkok
0
1 версия импортирована: Шаблон:Шаблоны для документирования
wikitext
text/x-wiki
{{ {{{|safesubst:}}}#ifeq:{{ {{{|safesubst:}}}NAMESPACE}}|{{NAMESPACE}}
|{{{no|{{{2|}}}}}}
|{{{yes|{{{1|}}}}}}
}}<noinclude>
{{Documentation}}
</noinclude>
4f51452ff12b7e72ad15c39cba7e3cc7a76b39d4
Шаблон:Optp
10
239
579
2021-08-30T19:34:41Z
ruwiki>WerySkok
0
1 версия импортирована: Шаблон:Шаблоны для документирования
wikitext
text/x-wiki
{{{{{|safesubst:}}}#invoke: Template call code | onlyParams }}<noinclude>{{doc}}</noinclude>
3e116ca0e893f9ea7b938dae72067678b03bc173
Шаблон:Optp/color
10
240
581
2021-08-30T19:34:42Z
ruwiki>WerySkok
0
1 версия импортирована: Шаблон:Шаблоны для документирования
wikitext
text/x-wiki
{{{{{|safesubst:}}}ifsubst|1=<!--
--><code style="color: {{optp/color}};">{{{1}}}</code>|2=<!--
--><nowiki>#</nowiki>888888<!--
-->}}<noinclude>
[[Категория:Шаблоны:Подстраницы шаблонов]]
[[Категория:Шаблоны:Цвет]]
[[Категория:Шаблоны:Используемые с подстановкой]]
</noinclude>
571a67174168634a24211fe1d5fcaa4727e150f1
Шаблон:Пример
10
241
583
2021-08-30T19:35:05Z
ruwiki>WerySkok
0
1 версия импортирована: Шаблон:Шаблоны для документирования
wikitext
text/x-wiki
<includeonly>{{#invoke:Example|main}}</includeonly><noinclude>{{doc}}</noinclude>
6c4efd62aa820f26f326813cddd4cfd909b9bd7a
Модуль:Example
828
242
585
2021-08-30T19:35:08Z
ruwiki>WerySkok
0
1 версия импортирована: Шаблон:Шаблоны для документирования
Scribunto
text/plain
local p = {}
-- используется для того, чтобы можно было удалять элементы из таблицы
local function copy(other)
local res = {}
for k,v in pairs(other) do
res[k] = v
end
return res
end
-- вызов шаблона, при ошибке возвращает пустую строку
local function expand(frame, tname, targs)
local success, result = pcall(
frame.expandTemplate,
frame,
{title = tname, args = targs}
)
if success then
return result
else
return ''
end
--return frame:expandTemplate({title = tname, args = args})
end
--предотвращает обработку вики-текста в отображении образца
local function nowiki(str)
local res = str
str = mw.text.unstripNoWiki(str)
str = string.gsub(str, '%[', '[')
str = string.gsub(str, '%]', ']')
str = string.gsub(str, '<', '<')
str = string.gsub(str, '>', '>')
str = string.gsub(str, '{', '{')
str = string.gsub(str, '|', '|')
str = string.gsub(str, '}', '}')
str = string.gsub(str, '\'', ''')
str = string.gsub(str, '"', '"')
str = string.gsub(str, '(://)', '<span>%1</span>')
return str
end
--удаляет из параметров вписанные через HTML-сущности "<nowiki>" и заменяет "{{=}}" на "=" для вызова шаблона
local function process_nowiki_equals(str)
str = str:gsub('<nowiki>', ''):gsub('</nowiki>', '')
:gsub('<nowiki>', ''):gsub('</nowiki>', '')
:gsub('{{=}}', '=')
:gsub('{{=}}', '=')
:gsub('{{=}}', '=')
:gsub('{{=}}', '=')
:gsub('&', '&')
return str
end
function p.main(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
local yesno = require('Module:Yesno')
local args = copy(getArgs(frame, {trim = false, removeBlanks = false})) --copy(frame.args)
local tag = args._tag
local container = args._container or nil
local ucFirst = yesno(args._u, false)
local link = yesno(args._link, false)
local sep = args._sep and args._sep .. ' '
local endl = args._endl or ''
local prefix = args._prefix or args['_pre-text'] or ''
local postfix = args._postfix or args['_post-text'] or ''
local nobr = yesno(args._nobr, false)
local spaced = yesno(args._spaced, false)
local nocat = yesno(args._nocat, false)
local style = args._style
if style == '' then
style = nil
end
-- передаётся шаблоном {{стопка примеров}}, один разделитель на все примеры
local comment_sep = args._comment_sep
-- полезно в шаблоне {{стопка примеров}} (это просто текст в конце)
local after = args._after or args._comment
-- полезно в шаблоне {{стопка примеров}} (это просто текст в начале)
local before = args._before and args._before .. ' ' or ''
if style == 'pre' then
if not (tag or container) then
container = 'pre'
end
sep = sep or '\n'
elseif style == '*pre' then
if not (tag or container) then
container = '*pre'
end
sep = sep or '\n'
elseif style == 'pre↓' then
if not (tag or container) then
container = 'pre'
end
-- содержимое шаблона {{sp↓|50%||-0.5em}}
sep = sep or '<div style="margin:-0.5em 50% 0.7em;"><span style="font-size:150%;">↓</span></div>\n'
elseif style == '*pre↓' then
if not (tag or container) then
container = '*pre'
end
-- содержимое шаблона {{sp↓|50%||-0.5em}}
sep = sep or '<div style="margin:-0.5em 50% 0.7em;"><span style="font-size:150%;">↓</span></div>\n'
elseif style == 'wikitable' then
if not (tag or container) then
tag = 'kbd'
end
sep = sep or '\n| '
comment_sep = '\n| '
end
if not (tag or container) then
tag = 'code'
end
if not sep then
sep = '→ '
end
if not comment_sep then
comment_sep = ' '
end
if (after) then
if not style then
after = '<small>' .. after .. '</small>'
end
after = comment_sep .. after
end
if not after then
after = ''
end
local nwt
if tag then
nwt = mw.html.create(tag):tag(tag) -- "no-wiki tag", внутри него шаблон не вызывается
if nobr then
nwt:css('white-space', 'nowrap')
end
end
local content = nowiki(prefix) .. '{{' -- для накопления содержимого тэга
local tname = args._template or args[1]
if tname == nil then -- если имя шаблона содержит знак "=" (работает, только если нет неименованных параметров)
local nextfunc, static, cur = pairs(args)
local k, v = nextfunc(static, cur)
if k ~= nil and type(k) ~= 'number' and not k:find('^_') then -- именованные параметры, исключая модификаторы внешнего вида
tname = k .. "=" .. v
args[k] = nil --больше этот параметр нам не пригодится
end
end
if tname == '' or tname == nil then -- при опущенном первом параметре берём имя шаблона из названия страницы
local ru = mw.language.new('ru')
local currentTitle = mw.title.getCurrentTitle().rootText
if not ucFirst and
((ru:uc(currentTitle) ~= currentTitle and -- названия со всеми заглавными буквами
not mw.ustring.match(currentTitle, '^[А-Яа-яA-Za-z]+:?[А-ЯA-Z]') -- Книга:Литературное наследство, TranslateDate
) or
#currentTitle == 1
)
then
tname = ru:lcfirst(currentTitle)
else
tname = currentTitle
end
end
-- Имя вызываемого шаблона в неименованном первом параметре (или же взято из названия страницы или
-- из именованного параметра в отсутствие неименованных — в следующей строчке вреда нет в любом случае),
-- больше его обрабатывать не надо
if args._template == nil then
table.remove(args,1)
end
if link then
content = content .. '[[Шаблон:' .. tname .. '|' .. tname .. ']]'
else
content = content .. tname
end
content = content .. endl
local targs, equals_pos, param, value, left_shift = {}, 0, '', '', 0
for k, v in pairs(args) do
if type(k) == 'number' then -- неименованные параметры
equals_pos = v:find('=')
if equals_pos and v:find('{{=}}') == equals_pos-2 then
equals_pos = nil
end
if equals_pos then -- содержащие "=" преобразуем в именованные
param = v:sub(1, equals_pos-1)
value = v:sub(equals_pos+1)
targs[param] = process_nowiki_equals(value)
content = content .. (spaced and ' ' or '') .. '|' .. nowiki(param) .. '=' .. nowiki(value) .. endl
left_shift = left_shift + 1 -- переменная нужна, чтобы квазинумерованные параметры, переданные через "{{=}}",
-- не сбивали порядок
else -- истинно неименованные
targs[k - left_shift] = process_nowiki_equals(v)
content = content .. (spaced and ' ' or '') .. '|' .. nowiki(v) .. endl
end
elseif not k:find('^_') then -- именованные параметры, исключая модификаторы внешнего вида
targs[k] = process_nowiki_equals(v)
content = content .. (spaced and ' ' or '') .. '|' .. nowiki(k) .. '=' .. nowiki(v) .. endl
end
end
if spaced then
content = content .. ' '
end
content = content .. '}}' .. nowiki(postfix)
if container then
local container_args = {}
container_args[1] = content
nwt = expand(frame, container, container_args)
else
nwt:wikitext(content):done()
end
if nocat then
targs['nocat'] = 1
end
expand_result = tostring(expand(frame, tname, targs))
if expand_result:sub(1, 2) == '{|' then
sep = sep .. '\n'
end
return before .. tostring(nwt) .. ' ' .. sep .. prefix .. expand_result .. postfix .. after
end
return p
bbcc2db5eb699c86d081437122681304ac0c12b8
Шаблон:Namespace detect
10
233
533
2021-08-30T19:43:11Z
ruwiki>WerySkok
0
wikitext
text/x-wiki
{{#switch:
{{lc: <!--Lower case the result-->
<!--If no or empty "demospace" parameter then detect namespace-->
{{#if:{{{demospace|}}}
| {{{demospace}}}
| {{#ifeq:{{NAMESPACE}}|{{ns:0}}
| main
| {{#ifeq:{{NAMESPACE}}|{{TALKSPACE}}
| {{#if:{{{talk|}}} | talk | {{#if:{{{andtalk|}}}|{{SUBJECTSPACE}}|talk}} }}
| {{NAMESPACE}}
}}
}}
}}
}}
<!-- Only one of the lines below will be executed -->
<!-- Respecting empty parameters on purpose -->
| main = {{{main| {{{other|}}} }}}
| talk
| обсуждение = {{{talk| {{{other|}}} }}}
| user
| участник = {{{user| {{{other|}}} }}}
| wikipedia
| википедия = {{{wikipedia| {{{other|}}} }}}
| file
| image
| файл = {{{file| {{{image| {{{other|}}} }}} }}}
| mediawiki
| медиавики = {{{mediawiki| {{{other|}}} }}}
| template
| шаблон = {{{template| {{{other|}}} }}}
| help
| справка = {{{help| {{{other|}}} }}}
| category
| категория = {{{category| {{{other|}}} }}}
| portal
| портал = {{{portal| {{{other|}}} }}}
| other
| #default = {{{other|}}} <!--"demospace=other" or a new namespace-->
}}<!--End switch--><noinclude>
{{documentation}}{{Указание авторства русскоязычной Википедии}}
</noinclude>
058c2deda5bf3cd3190672c4b14ab9f0c072ce03
Шаблон:=
10
243
589
2021-08-30T20:10:13Z
ruwiki>WerySkok
0
1 версия импортирована
wikitext
text/x-wiki
=<noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude>
014d0de3d5673019255be0e21b88cdb2037871db
Шаблон:Docpage
10
178
529
2021-08-30T20:10:36Z
ruwiki>WerySkok
0
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{#ifeq: {{SUBPAGENAME}} | doc
| {{fmbox
| class = hlist nowraplinks
| style = margin-bottom:1em; background:#eaf3ff; border:1px solid #a3caff;
| image = [[Файл:OOjs UI icon info.svg|24px|link=|alt=]]
| text = <div>
* [[:{{#titleparts: {{SUBJECTPAGENAME}} | -1 }}]]
* [[:{{SUBJECTPAGENAME}}|Документация]]
* [[{{#titleparts: {{TALKPAGENAME}} | -1 }}|Обсуждение]]
* [[Служебная:Whatlinkshere/{{#titleparts: {{SUBJECTPAGENAME}} | -1 }}|Где используется]] <!-- {{#ifeq: {{NAMESPACE}} | {{ns:Template}} |
** {{Параметры шаблона|{{#titleparts: {{PAGENAME}} | -1 }}}}
}} --></div><!--
-->{{#if: {{{nocat|}}} || {{#ifexist: {{NAMESPACE}}:{{BASEPAGENAME}} || [[Категория:Шаблоны:Документация несуществующих шаблонов]] }} }}
}}{{#if: {{{nocat|}}} || {{#ifeq: {{NAMESPACE}}
| Модуль
| [[Категория:Модули:Документация]]
| [[Категория:Шаблоны:Документация]]
}}
}}
}}</includeonly><noinclude>{{doc}}</noinclude>
7f27a8c87a1da2f25ea94fb8ad4600fc9bd009a5
Шаблон:Tc
10
244
591
2021-08-30T20:10:52Z
ruwiki>WerySkok
0
1 версия импортирована
wikitext
text/x-wiki
{{{{{|safesubst:}}}#invoke: Template call code | withParams | _tag = {{{_tag|code}}} }}<noinclude>{{doc}}</noinclude>
db6f042f5bfd10e28e4554066fa696babcc884b2
Шаблон:Карточка
10
129
639
2021-08-30T20:11:34Z
ruwiki>WerySkok
0
1 версия импортирована
wikitext
text/x-wiki
<table class="infobox {{{класс_тела|}}}" style="{{{стиль_тела|}}}" {{#if:{{{имя|}}}|{{#ifeq:{{{имя|}}}|-||data-name="{{{имя}}}"}}}}><!--
Вверху0
-->{{#if:{{{вверху0|}}}|<tr><td colspan="2" class="{{{класс_вверху0|}}}" style="text-align:center; {{{стиль_вверху0|}}}">{{{вверху0}}}</td></tr>}}<!--
Вверху
-->{{#if:{{{вверху|}}}|<tr><th colspan="2" class="infobox-above {{{класс_вверху|}}}" style="{{{стиль_вверху|}}}">{{{вверху}}}</th></tr>}}<!--
Вверху2
-->{{#if:{{{вверху2|}}}|<tr><td colspan="2" class="{{{класс_вверху2|}}}" style="text-align:center; {{{стиль_вверху2|}}}">{{{вверху2}}}</td></tr>}}<!--
Вверху3
-->{{#if:{{{вверху3|}}}|<tr><td colspan="2" class="{{{класс_вверху3|}}}" style="text-align:center; {{{стиль_вверху3|}}}">{{{вверху3}}}</td></tr>}}<!--
Изображение
-->{{#if:{{{изображение|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения|}}}" style="{{{стиль_изображения|}}}"> {{{изображение}}} {{#if:{{{подпись|}}}|
<div class="media-caption" style="{{{стиль_подписи|}}}">{{{подпись}}}</div>}}</td></tr>}}<!--
Изображение2
-->{{#if:{{{изображение2|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения2|}}}" style="{{{стиль_изображения2|}}}"> {{{изображение2}}} {{#if:{{{подпись2|}}}|
<div class="media-caption" style="{{{стиль_подписи2|}}}">{{{подпись2}}}</div>}}</td></tr>}}<!--
Изображение3
-->{{#if:{{{изображение3|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения3|}}}" style="{{{стиль_изображения3|}}}"> {{{изображение3}}} {{#if:{{{подпись3|}}}|
<div class="media-caption" style="{{{стиль_подписи3|}}}">{{{подпись3}}}</div>}}</td></tr>}}<!--
Строки
-->{{#invoke:Infobox|renderLines}}<!--
Внизу
-->{{Карточка/внизу|
стиль_внизу_общий={{{стиль_внизу|}}}|
класс_внизу={{{класс_внизу|}}}|
внизу={{{внизу|}}}}}<!--
Внизу N
-->{{#invoke:Transclude|npc|Карточка/внизу|
стиль_внизу_общий={{{стиль_внизу|}}}|
стиль_внизу=|
класс_внизу=|
внизу=}}
</table><includeonly><!--
статьи
-->{{#if:{{NAMESPACE}}||<!--
-->{{#if:{{{имя|}}}||[[Категория:Статьи с шаблонами-карточками без имени]]}}<!--
-->{{#ifeq:{{{имя|}}}|{{subst:PAGENAME}}|[[Категория:Статьи с шаблонами-карточками без имени]]}}<!--
-->}}<!--
шаблоны
-->{{#ifeq:{{NAMESPACENUMBER}}|10|<!--
-->{{#if:{{{имя|}}}||[[Категория:Шаблоны-карточки без имени]]}}<!--
-->{{#ifeq:{{{имя|}}}|{{subst:PAGENAME}}|[[Категория:Шаблоны-карточки без имени]]}}<!--
-->{{#if:{{{название|}}}{{{стиль_названия|}}}|[[Категория:Шаблоны с использованием параметра «название» в шаблоне «Карточка»]]}}<!--
-->{{#if:{{{подпись|}}}{{{стиль_подписи|}}}{{{подпись2|}}}{{{стиль_подписи2|}}}{{{подпись3|}}}{{{стиль_подписи3|}}}|[[Категория:Шаблоны с использованием параметра «подпись» в шаблоне «Карточка»]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_тела|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_названия|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху2|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху3|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи2|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи3|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_заголовков|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_меток|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_текста|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_внизу|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifeq:{{{имя|}}}|{{PAGENAME}}| [[Категория:Шаблоны-карточки по алфавиту|{{ucfirst:{{без начала|{{PAGENAME}}|Карточка }}}}]]}}<!--
-->}}<!--
любое пространство имён
-->{{#if:{{{название|}}}{{{стиль_названия|}}}|[[Категория:Страницы с использованием параметра «название» в шаблоне «Карточка»]]}}<!--
-->{{#if:{{{подпись|}}}{{{стиль_подписи|}}}{{{подпись2|}}}{{{стиль_подписи2|}}}{{{подпись3|}}}{{{стиль_подписи3|}}}|[[Категория:Страницы с использованием параметра «подпись» в шаблоне «Карточка»]]}}</includeonly><noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude>
8b14ccc682362e6ed5a194621133805aea17ab0d
Шаблон:Optp/comment
10
245
593
2021-08-30T20:28:35Z
ruwiki>WerySkok
0
1 версия импортирована
wikitext
text/x-wiki
<p style="font-size:85%;">Серым {{#ifeq: {{{1|}}} | 1 | показан необязательный параметр | показаны необязательные параметры }}.</p><noinclude>
{{doc-inline}}
* {{пример|optp/comment}}
* {{пример|optp/comment|1}}
{{doc-end}}
[[Категория:Шаблоны:Подстраницы шаблонов]]
</noinclude>
57a6d9eaf58c69ac5e07d5a55c4de17d34d427bf
Шаблон:^
10
246
595
2021-08-30T20:28:46Z
ruwiki>WerySkok
0
1 версия импортирована
wikitext
text/x-wiki
<div style=margin-top:{{#if:{{{1|}}}|{{{1}}}|2em}}></div><noinclude>{{doc}}<!-- Пожалуйста, добавляйте категории и интервики на страницу документации! --></noinclude>
8a2941bfb74cc487b19b1ce656a0d7b49cfb9a8e
Шаблон:Sp↓
10
249
601
2021-08-30T20:29:10Z
ruwiki>WerySkok
0
1 версия импортирована
wikitext
text/x-wiki
<div style="margin-left:{{#if: {{{1|}}} | {{{1}}} | 1.3em }}; {{#if: {{{2|}}} | margin-top:{{{2}}}; }} margin-bottom:{{#if: {{{3|}}} | {{{3}}} | 0.7em }};"><span style="font-size:{{#if: {{{size|}}} | {{{size}}} | {{#ifeq: {{str find|{{{1|}}}|%}} | -1 | 120% | 150% }} }};">↓</span></div><noinclude>{{doc}}</noinclude>
e0d0479cdd64d3e90be2c1c2d1b3c3502312f926
Шаблон:Днш
10
250
603
2021-08-30T20:29:11Z
ruwiki>WerySkok
0
1 версия импортирована
wikitext
text/x-wiki
#REDIRECT [[Шаблон:Другие названия шаблона]]
310154c4badc00ae3faf727456b5aba85e337ba6
Шаблон:Abbr
10
232
517
2021-08-31T11:40:52Z
ruwiki>WerySkok
0
wikitext
text/x-wiki
<includeonly>{{#switch: {{{3|1}}}
| 0 = <abbr title="{{#tag:nowiki|{{replace|{{{2}}}|"|"}}}}">{{{1}}}</abbr>
| 1 = [[{{{1}}}|<abbr title="{{#tag:nowiki|{{replace|{{{2}}}|"|"}}}}">{{{1}}}</abbr>]]
| 2 = [[{{{2}}}|<abbr title="{{#tag:nowiki|{{replace|{{{2}}}|"|"}}}}">{{{1}}}</abbr>]]
| #default = [[{{{3}}}|<abbr title="{{#tag:nowiki|{{replace|{{{2}}}|"|"}}}}">{{{1}}}</abbr>]]
}}</includeonly><noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude>
adac845cdff938e70ffb8d2c92101be40d204e3b
Шаблон:Abbr/doc
10
248
599
2021-08-31T11:48:42Z
ruwiki>WerySkok
0
wikitext
text/x-wiki
{{docpage}}
Этот шаблон выделяет [[w:ru:Аббревиатура|аббревиатуру]] подчёркиванием и добавляет к ней всплывающую подсказку с расшифровкой. Он во многом похож на шаблон {{tl|comment}}.
Шаблон может установить ссылку на статью, имя которой — значение 1-го, 2-го или 3-го параметра, например: {{abbr|РФ|Российская Федерация|w:ru:Россия}}.
{{днш|аббревиатура|аббр}}
== Использование ==
{{tc||''аббревиатура''|''расшифровка''{{optp|''№ параметра для ссылки или 0, чтобы подавить ссылку''}}}}
{{optp/comment}}{{^|1em}}
Необязательный третий параметр указывает, какой из параметров использовать для ссылки в качестве названия статьи.
* <code>0</code> — подавить ссылку
* <code>1</code> (по умолчанию) — использовать 1-й параметр (<code>''аббревиатура''</code>)
* <code>2</code> — использовать 2-й параметр (<code>''расшифровка''</code>)
* другое — использовать 3-й (этот же) параметр
== Примеры ==
* Ссылка подавлена:
: {{пример||ПТЗ|Павлодарский тракторный завод|0}}
* Ссылка по умолчанию или явно использует содержимое 1-го параметра:
: {{tc||w:ru:АН СССР|Академия наук СССР}}<br><span style="margin-left: 6px;">или</span><br>{{пример||w:ru:АН СССР|Академия наук СССР|1|_sep={{sp↓|||0}}}} <!-- интервики на википедию чтоб не требовало страниц -->
* Ссылка использует содержимое 2-го параметра:
: {{пример||ПАВ|w:ru:поверхностно-активные вещества|2}}
* Ссылка на произвольную страницу в 3-м параметре:
: {{пример||ПАВ|поверхностно-активные вещества|w:ru:Психоактивные вещества}}
: В данном случае ПАВ расшифровано как «поверхностно-активные вещества», ссылка указывает на статью «[[w:ru:Психоактивные вещества|Психоактивные вещества]]».
== Технические ограничения ==
Технические ограничения те же, что и в шаблоне {{tl|comment}}.
* Если в параметрах шаблона есть знак <code>=</code>, то, как и в любом другом шаблоне, приходится использовать явные номера параметров: {{tc|comment|1{{=}}текст|2{{=}}подсказка}}.
* В некоторых браузерах длина всплывающей подсказки ограничена. Например, в браузере Mozilla Firefox до третьей версии подсказки были однострочными.
* Пользователи [[w:ru:смартфон|смартфонов]] и [[w:ru:Планшетный компьютер|планшетных компьютеров]], как правило, не имеют возможности увидеть всплывающую подсказку, поэтому используйте данный шаблон только там, где это действительно необходимо.
<includeonly>
[[Категория:Шаблоны:Форматирование]]
[[Категория:Шаблоны:Внутренние ссылки]]
</includeonly>
060aec5d84b5320d02f9c95e1cd0427e110f1315
Шаблон:Другие названия шаблона
10
247
597
2021-08-31T11:50:38Z
ruwiki>WerySkok
0
wikitext
text/x-wiki
<includeonly>[[w:ru:ВП:Перенаправления|{{#if:{{{2|}}}|Другие названия|Другое название}}]] этого шаблона{{#if:{{{2|}}}|:| —}} <!--
-->{{#if:{{{1|}}}|{{t|{{{1}}}|noredir}} |<strong class=error>Не указано ни одного альтернативного названия!</strong>}}<!--
-->{{#if:{{{2|}}}|, {{t|{{{2}}}|noredir}} }}<!--
-->{{#if:{{{3|}}}|, {{t|{{{3}}}|noredir}} }}<!--
-->{{#if:{{{4|}}}|, {{t|{{{4}}}|noredir}} }}<!--
-->{{#if:{{{5|}}}|, {{t|{{{5}}}|noredir}} }}<!--
-->{{#if:{{{6|}}}|, {{t|{{{6}}}|noredir}} }}<!--
-->{{#if:{{{7|}}}|, {{t|{{{7}}}|noredir}} }}<!--
-->{{#if:{{{8|}}}|, {{t|{{{8}}}|noredir}} }}<!--
-->{{#if:{{{9|}}}| [{{fullurl:Служебная:Ссылки сюда/{{FULLPAGENAMEE}}|hidelinks=1&hidetrans=1}} и др.]|{{#if:{{{comment|}}}| ({{{comment}}})}}}}.</includeonly><noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude>
7b543dddf959926ff3a8b3d1ae7894515a88b0a0
Шаблон:Big
10
73
631
118
2021-08-31T11:51:12Z
ruwiki>WerySkok
0
wikitext
text/x-wiki
<span style="font-size:120%;">{{{1}}}</span><noinclude>
{{documentation}}{{Указание авторства русскоязычной Википедии}}
<!-- PLEASE ADD CATEGORIES TO THE /doc SUBPAGE, THANKS -->
</noinclude>
c98715ace316ced3e534c85a0061a40c996f9cec
Шаблон:Clear
10
188
519
420
2021-08-31T11:51:48Z
ruwiki>WerySkok
0
wikitext
text/x-wiki
<div style="clear:{{{1|both}}};"></div><noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude>
658ab2d07ec1af4be2ebb95507ab98803c483513
Шаблон:Doc
10
171
521
2021-08-31T11:52:10Z
ruwiki>WerySkok
0
wikitext
text/x-wiki
<includeonly>{{doc/begin|{{SUBJECTSPACE}}:{{PAGENAME:{{{1|{{SUBJECTPAGENAME}}/doc}}}}}|editsection={{{editsection|}}}}}
{{#if:{{{1|}}}|{{#ifexist:{{{1}}}|{{{{{1}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}|{{{5|}}}}}|{{#ifexist:{{SUBJECTSPACE}}:{{{1}}}|{{{{{1}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}|{{{5|}}}}}|{{Документировать|{{{1}}}}}}}}}|{{#ifexist:{{SUBJECTPAGENAME}}/doc|{{{{SUBJECTPAGENAME}}/doc}}|{{Документировать|{{SUBJECTPAGENAME}}/doc}}}}}}
{{doc/end}}</includeonly><noinclude>
{{doc}}{{Указание авторства русскоязычной Википедии}}
<!--
[Rus]: Добавляйте категории и интервики на подстраницу /doc, не сюда!
[Eng]: Please add categories and interwiki links to the /doc subpage, not here!
-->
</noinclude>
b75033813bba7eb90a8976d597febd1d93bcecab
Шаблон:Doc/begin
10
172
523
2021-08-31T11:52:31Z
ruwiki>WerySkok
0
wikitext
text/x-wiki
<includeonly><templatestyles src="Шаблон:Doc/styles.css" />{{clear}}<div>{{якорь|Документация|doc}}</div>
<div class="ts-doc-doc">
<div class="ts-doc-header">
<div class="ts-doc-heading">Документация</div>
{{#if: {{{inline|}}} || {{tlinks|lc={{{1}}}|nowatch=yes}} }}
</div>
<div class="ts-doc-content"></includeonly><noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude>
aafe3c200059d98000a15745eb3a16b332048322
Шаблон:Doc/styles.css
10
173
527
2021-08-31T11:54:21Z
ruwiki>WerySkok
0
sanitized-css
text/css
.ts-doc-doc {
background-color: #eaf3ff;
border: 1px solid #a3caff;
margin-top: 1em;
}
.ts-doc-header {
background-color: #c2dcff;
padding: .642857em 1em .5em;
overflow: hidden;
}
.ts-doc-header .ts-tlinks-tlinks {
line-height: 24px;
}
.ts-doc-header .ts-tlinks-tlinks a.external {
color: #0645ad;
}
.ts-doc-header .ts-tlinks-tlinks a.external:visited {
color: #0b0080;
}
.ts-doc-header .ts-tlinks-tlinks a.external:active {
color: #faa700;
}
.ts-doc-content {
padding: .214286em 1em;
}
.ts-doc-content:after {
content: '';
clear: both;
display: block;
}
.ts-doc-heading {
display: inline-block;
padding-left: 30px;
background: url(//upload.wikimedia.org/wikipedia/commons/c/ca/OOjs_UI_icon_info.svg) center left/24px 24px no-repeat;
height: 24px;
line-height: 24px;
font-size: 13px;
font-weight: 600;
letter-spacing: 1px;
text-transform: uppercase;
}
.ts-doc-content > *:first-child,
.ts-doc-footer > *:first-child {
margin-top: .5em;
}
.ts-doc-content > *:last-child,
.ts-doc-footer > *:last-child {
margin-bottom: .5em;
}
.ts-doc-footer {
background-color: #eaf3ff;
border: 1px solid #a3caff;
padding: .214286em 1em;
margin-top: .214286em;
margin-bottom: .214286em;
font-style: italic;
}
@media (max-width: 719px) {
.ts-doc-header .ts-tlinks-tlinks {
float: none;
}
}
/* Данный шаблон использует материал из страницы [[w:ru:Шаблон:Doc/styles.css]] с русскоязычной Википедии, который выпущен под лицензией Creative Commons Attribution-ShareAlike 3.0 Unported.
[[Категория:Шаблоны:Подстраницы CSS]] */
569be9051ed08a2fc9715c629fb275f499513915
Шаблон:Join
10
150
531
342
2021-08-31T11:54:56Z
ruwiki>WerySkok
0
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>#invoke:Separated entries|main|separator={{{separator|}}}}}<noinclude>
{{doc}}{{Указание авторства русскоязычной Википедии}}
<!-- Категории — на подстраницу /doc, интервики — в Викиданные. -->
</noinclude>
af3b635654ed05178cb618c5ae74d630f683b14b
Шаблон:Ombox
10
20
609
2021-08-31T11:55:31Z
ruwiki>WerySkok
0
wikitext
text/x-wiki
{{#invoke:Message box|ombox}}<noinclude>
{{doc}}{{Указание авторства русскоязычной Википедии}}<!-- Add categories and interwikis to the /doc subpage, not here! --></noinclude>
d6812e2b9ef235ed760e3d51553c6a00fbddec09
Шаблон:Replace
10
145
535
2021-08-31T11:55:45Z
ruwiki>WerySkok
0
wikitext
text/x-wiki
{{{{{|safesubst:}}}#invoke:String|replace|source={{{1}}}|{{{2}}}|{{{3}}}|count={{{count|}}}}}<noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude>
1e93df448b55000320615b7fb5a0678e470ff5ff
Шаблон:Str left
10
146
537
334
2021-08-31T11:55:53Z
ruwiki>WerySkok
0
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>padleft:|{{{2|1}}}|{{{1|}}}}}<noinclude>
{{doc}}{{Указание авторства русскоязычной Википедии}}
</noinclude>
c84e4fa3913bb778eebb4e7967691f2a54ccf7f4
Шаблон:Str len
10
166
539
374
2021-08-31T11:56:07Z
ruwiki>WerySkok
0
wikitext
text/x-wiki
{{{{{|safesubst:}}}#invoke:String|len|s={{{1|}}}}}<noinclude>
{{doc}}{{Указание авторства русскоязычной Википедии}}
<!-- Add categories and interwikis to the /doc subpage, not here! -->
</noinclude>
64072366351eb0f17ebd1d769946190837e1fc9d
Шаблон:Str rightc
10
167
541
376
2021-08-31T11:56:22Z
ruwiki>WerySkok
0
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>Str sub|{{{1}}}|{{<includeonly>safesubst:</includeonly>#expr:{{<includeonly>safesubst:</includeonly>Str len|{{{1}}}}}-{{{2}}}}}|{{{2}}}}}<noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude>
a3a090a23406df9276554e488f593ed68cfd2e03
Шаблон:Str sub
10
164
543
370
2021-08-31T11:56:34Z
ruwiki>WerySkok
0
wikitext
text/x-wiki
<includeonly>{{{{{|safesubst:}}}#invoke:String|sublength|s={{{1}}}|i={{{2|0}}}|len={{{3|0}}}}}</includeonly><noinclude>
{{doc}}{{Указание авторства русскоязычной Википедии}}
</noinclude>
23deaf74186354efc10b9054b8b8f2da2dc98a34
Шаблон:Tag
10
72
633
2021-08-31T11:57:02Z
ruwiki>WerySkok
0
wikitext
text/x-wiki
<{{#ifeq: {{{style|}}} | regular | span | code }} class="{{#ifeq: {{{wrap|}}} | yes | wrap | nowrap }}" style="{{#switch: {{{style|}}}
| plain = border:none; background:transparent;
| regular =
| {{{style|}}}
}}"><!--
Opening tag
-->{{#switch: {{#if: {{{2|}}} | {{{2|}}} | pair }}
|c|close =
|s|single
|o|open
|p|pair = {{#ifeq: {{{1|tag}}}
| !--
| {{#ifeq: {{{style|}}} | regular | <span class="wp-templatelink"><!--</span> | <!-- }}
| {{#ifeq: {{{style|}}} | regular | <span class="wp-templatelink"><</span> | < }}{{{1|tag}}}{{#if: {{{params|{{{p|}}}}}} |  {{{params|{{{p|}}}}}} }}
}}
}}<!--
Content between tags
-->{{#switch: {{#if: {{{2|}}} | {{{2|}}} | pair }}
|c|close = {{{content|{{{c|}}}}}}
|s|single =  {{#ifeq: {{{style|}}} | regular | <span class="wp-templatelink">/></span> | /> }}
|o|open = {{#ifeq: {{{style|}}} | regular | <span class="wp-templatelink">></span> | > }}{{{content|{{{c|}}}}}}
|p|pair = {{#ifeq: {{{1|tag}}} | !-- || {{#ifeq: {{{style|}}} | regular | <span class="wp-templatelink">></span> | > }} }}{{{content|{{{c|}}}}}}
}}<!--
Closing tag
-->{{#switch: {{#if: {{{2|}}} | {{{2|}}} | pair }}
|s|single
|o|open =
|c|close
|p|pair = {{#ifeq: {{{1|tag}}}
| !--
| {{#ifeq: {{{style|}}} | regular | <span class="wp-templatelink">--></span> | --> }}
| {{#ifeq: {{{style|}}} | regular | <span class="wp-templatelink"></</span>{{{1|tag}}}<span class="wp-templatelink">></span> | </{{{1|tag}}}> }}
}}
}}<!--
--></{{#ifeq: {{{style|}}} | regular | span | code }}><noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude>
20b34607cde77ca9d1e04d50395bb22f556175d6
Шаблон:Действия для страницы
10
174
555
2021-08-31T11:57:14Z
ruwiki>WerySkok
0
wikitext
text/x-wiki
<templatestyles src="Шаблон:Действия для страницы/styles.css" /><div style="{{#ifeq: {{yesno-yes|{{{right|}}}}} | yes || float:none; }} {{#if: {{{fontsize|}}} | font-size:{{{fontsize|}}}px; }}" class="ts-tlinks-tlinks plainlinks"><span class="mw-editsection-bracket">[</span><!--
-->{{join|separator=<span class="mw-editsection-divider"> &#124; </span>
|1={{#ifexist: {{#rel2abs: {{{lc|}}} }}
| {{#ifeq: {{{dislooklink|{{{noview|}}}}}} | yes || [[{{{lc}}}|просмотр]] }}
}}
|2={{#ifexist: {{#rel2abs: {{{lc|}}} }}
| [[Special:EditPage/{{#rel2abs: {{{lc}}} }}|править]]
}}
|3={{#ifexist: {{#rel2abs: {{{lc|}}} }}
| {{#ifeq: {{{dishistlink|{{{nohistory|}}}}}} | yes || [[Special:PageHistory/{{#rel2abs: {{{lc}}} }}|история]] }}
}}
|4={{#ifexist: {{#rel2abs: {{{lc|}}} }}
|
| [{{fullurl:{{#rel2abs: {{{lc}}} }}|action=edit&redlink=1}} создать]
}}
|5={{#ifeq: {{{diswatchlink|{{{nowatch|}}}}}} | yes || [{{fullurl:{{#rel2abs: {{{lc}}} }}|action=watch}} следить] }}
|6={{#ifeq: {{{disupdlink|{{{noupdate|}}}}}} | yes || <span class="purgelink" data-pagename="{{{lc|{{FULLPAGENAME}}}}}">[[Special:Purge/{{{lc|{{FULLPAGENAME}}}}}|обновить]]</span> }}
}}<span class="mw-editsection-bracket">]</span></div><noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude>
8bb7f43b48bc8df9261d9908ae41e529a7ce2b76
Шаблон:Yesno
10
131
551
304
2021-08-31T11:57:38Z
ruwiki>WerySkok
0
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>#switch: {{<includeonly>safesubst:</includeonly>lc: {{{1|¬}}} }}
|no
|n
|нет
|false
|0 = {{{no|<!-- null -->}}}
| = {{{blank|{{{no|<!-- null -->}}}}}}
|¬ = {{{¬|}}}
|yes
|y
|да
|true
|1 = {{{yes|yes}}}
|#default = {{{def|{{{yes|yes}}}}}}
}}<noinclude>
{{Documentation}}{{Указание авторства русскоязычной Википедии}}
</noinclude>
c4869ee2d8dd9ac37c836c6827b5747ee662c680
Шаблон:Yesno-yes
10
153
553
2021-08-31T11:57:58Z
ruwiki>WerySkok
0
wikitext
text/x-wiki
{{yesno|{{{1}}}|yes={{{yes|yes}}}|no={{{no|no}}}|blank={{{blank|yes}}}|¬={{{¬|yes}}}|def={{{def|yes}}}}}<noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude>
1671b5ddb7308c399e9763990062634cdca2e416
Шаблон:Действия для страницы/styles.css
10
175
557
2021-08-31T11:59:39Z
ruwiki>WerySkok
0
sanitized-css
text/css
.ts-tlinks-tlinks {
font-weight: normal;
float: right;
font-size: 13px;
}
.ts-tlinks-tlinks .mw-editsection-divider {
display: inline;
}
/* Данный шаблон использует материал из шаблона [[w:ru:Шаблон:Действия для страницы/styles.css]] с русскоязычной Википедии, который выпущен под лицензией Creative Commons Attribution-ShareAlike 3.0 Unported.
[[Категория:Шаблоны:Подстраницы CSS]] */
54f9185e91e3e9570794c39f9c9829c7cab67759
Шаблон:Карточка/внизу
10
137
647
316
2021-09-01T19:26:20Z
ruwiki>WerySkok
0
wikitext
text/x-wiki
<includeonly>{{#if:{{{внизу|}}}|<tr><td colspan="2" class="infobox-below {{{класс_внизу|}}}" style="{{{стиль_внизу_общий|}}};{{{стиль_внизу|}}}">{{{внизу|}}}</td></tr>}}</includeonly><noinclude>
{{doc}}{{Указание авторства русскоязычной Википедии}}
</noinclude>
716990a6b019cac431163672bf5072536f075925
Шаблон:Якорь
10
236
561
2021-09-01T19:27:56Z
ruwiki>WerySkok
0
wikitext
text/x-wiki
{{#invoke:якорь|main}}<noinclude>
{{doc}}{{Указание авторства русскоязычной Википедии}}
<!-- Добавляйте категории на страницу документацию, не сюда -->
</noinclude>
d3f6a8195150483ee5b8b616a2aae7afbd3a3e0b
Шаблон:Str find
10
214
587
476
2021-09-01T19:28:50Z
ruwiki>WerySkok
0
wikitext
text/x-wiki
{{ {{{|safesubst:}}}#invoke:String|str_find|source={{{1|}}}|{{{2|}}}}}<noinclude>
{{doc}}{{Указание авторства русскоязычной Википедии}}
<!-- Add categories and interwikis to the /doc subpage, not here! -->
</noinclude>
30ca3557bed0ebaf84cb26b8d708526b29211ed7
Шаблон:Tl
10
162
547
366
2021-09-01T19:29:49Z
ruwiki>WerySkok
0
wikitext
text/x-wiki
{{{{{|safesubst:}}}#invoke: Template call code | withoutParams }}<noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude>
c6affa0b33f35b013da6f92eae77096f6a254def
Шаблон:OnLua
10
227
641
2021-09-01T19:32:23Z
ruwiki>WerySkok
0
wikitext
text/x-wiki
<includeonly>{{ombox
| small = yes
| style = width:23em;
| image = [[Файл:Lua-logo-nolabel.svg|40px|alt=Лого Lua|link=w:ru:Lua]]
| text = {{replace|Этот шаблон {{#if: {{{partly|}}} | частично }} реализован на основе [[w:ru:Lua|Lua]]{{#if:{{{module2|}}}{{{tech2|}}}|:<br><ul><li>}}{{#if:{{{1|}}}{{{tech|}}}| с использованием {{{tech|{{#if:{{{2|}}}|функции <code>{{#if:{{{line|}}}|[[Module:{{{1}}}#L-{{{line}}}|{{{2}}}()]]|[[{{{funcref|Module:{{{1}}}#{{{2}}}}}}|{{{2}}}()]]}}</code> из }}{{#if:{{{1|}}}|модуля [[Module:{{{1}}}|{{{1}}}]]}}}}};}}<!--
-->{{#invoke:Transclude|npc|OnLua/Строка|
module=
|function=
|tech=
|line=
}}.|;.|.}}{{#if:{{{module2|}}}{{{tech2|}}}|</ul>}} {{#if:{{{1|}}}{{{tech|}}}{{{module1|}}}{{{tech1|}}}||<div class="error"><small>'''Не указано название использующегося модуля!'''</small></div>}}
}}{{#ifeq:{{SUBPAGENAME}}|{{{doc|doc}}}||{{#if:{{{nocat|}}}||[[Категория:Шаблоны, использующие Scribunto]]{{#if:{{{1|}}}{{{tech|}}}{{{module1|}}}{{{tech1|}}}||[[Категория:Шаблоны, использующие Lua, без указания модуля]]}}}}}}</includeonly><noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude>
18395e40673a4d14410acb745ce1b85e01dce5b7
Шаблон:Doc/end
10
176
525
394
2021-09-01T19:34:08Z
ruwiki>WerySkok
0
wikitext
text/x-wiki
<includeonly></div>
</div><templatestyles src="Шаблон:Doc/styles.css" />{{#ifexpr: {{NAMESPACENUMBER}} mod 2 = 1 <!-- Например, [[Обсуждение MediaWiki:Robots.txt]] -->
| {{^|1em}}
| <div class="ts-doc-footer plainlinks">
{{#ifeq: {{str left|{{PAGENAME}}|9}}
| Песочница
|
| {{#ifeq: {{str rightc|{{PAGENAME}}|10}}
| /песочница
|
| Во избежание поломок страниц, использующих этот {{#ifeq: {{NAMESPACE}}
| Модуль
| модуль
| шаблон
}}, экспериментируйте в [[w:ru:Википедия:Правка и тестирование шаблонов в песочнице|песочнице]] <small style="font-style:normal;">({{#ifexist: {{FULLPAGENAME}}/песочница
| [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit}} редактировать] {{!}} [{{fullurl:Special:ComparePages|page1={{FULLPAGENAMEE}}&page2={{FULLPAGENAMEE}}/песочница}} разница] {{#ifexist: {{FULLPAGENAME}}/тесты | {{!}} [[{{FULLPAGENAME}}/тесты|тесты]] }}
| {{#ifeq: {{NAMESPACE}} | Модуль | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit}} создать] | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit&preload=Шаблон:Doc/предзагрузка-песочница}} создать] {{!}} [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit&preload=Шаблон:Doc/зеркало}} зеркало] }}
}})</small> или {{#ifeq: {{NAMESPACE}}
| Модуль
| [[w:ru:Модуль:Песочница|песочнице для модулей]]
| своём [[w:ru:ВП:ЛП|личном пространстве]]
}}.<br>
}}
}}{{#ifexist: {{FULLPAGENAME}}/doc | Пожалуйста, добавляйте категории на подстраницу [[/doc]]. }}[[Special:PrefixIndex/{{FULLPAGENAME}}/|Подстраницы этого {{#ifeq: {{NAMESPACE}}
| Модуль
| модуля
| шаблона
}}]].
</div>
}}</includeonly><noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude>
8681561dd39a26e0c52106f8dd32bc9ac6e2081f
Модуль:Unsubst
828
80
132
2021-09-24T10:34:57Z
ruwiki>Grain of sand
0
+ параметр $format
Scribunto
text/plain
local checkType = require('libraryUtil').checkType
local p = {}
local BODY_PARAM = '$B'
local specialParams = {
['$params'] = 'parameter list',
['$aliases'] = 'parameter aliases',
['$flags'] = 'flags',
['$format'] = 'date format',
['$B'] = 'template content'
}
function p.main(frame, body)
-- If we are substing, this function returns a template invocation, and if
-- not, it returns the template body. The template body can be specified in
-- the body parameter, or in the template parameter defined in the
-- BODY_PARAM variable. This function can be called from Lua or from
-- #invoke.
-- Return the template body if we aren't substing.
if not mw.isSubsting() then
if body ~= nil then
return body
elseif frame.args[BODY_PARAM] ~= nil then
return frame.args[BODY_PARAM]
else
error(string.format(
"no template content specified (use parameter '%s' from #invoke)",
BODY_PARAM
), 2)
end
end
-- Sanity check for the frame object.
if type(frame) ~= 'table'
or type(frame.getParent) ~= 'function'
or not frame:getParent()
then
error(
"argument #1 to 'main' must be a frame object with a parent " ..
"frame available",
2
)
end
-- Find the invocation name.
local mTemplateInvocation = require('Module:Template invocation')
local name = mTemplateInvocation.name(frame:getParent():getTitle())
-- Combine passed args with passed defaults
local args = {}
local format = frame.args['$format'] or 'j xg Y'
if string.find( ','..(frame.args['$flags'] or '')..',', ',%s*override%s*,' ) then
for k, v in pairs( frame:getParent().args ) do
args[k] = v
end
for k, v in pairs( frame.args ) do
if not specialParams[k] then
if v == '__DATE__' then
v = mw.getContentLanguage():formatDate( format )
end
args[k] = v
end
end
else
for k, v in pairs( frame.args ) do
if not specialParams[k] then
if v == '__DATE__' then
v = mw.getContentLanguage():formatDate( format )
end
args[k] = v
end
end
for k, v in pairs( frame:getParent().args ) do
args[k] = v
end
end
-- Trim parameters, if not specified otherwise
if not string.find( ','..(frame.args['$flags'] or '')..',', ',%s*keep%-whitespace%s*,' ) then
for k, v in pairs( args ) do args[k] = mw.ustring.match(v, '^%s*(.*)%s*$') or '' end
end
-- Pull information from parameter aliases
local aliases = {}
if frame.args['$aliases'] then
local list = mw.text.split( frame.args['$aliases'], '%s*,%s*' )
for k, v in ipairs( list ) do
local tmp = mw.text.split( v, '%s*>%s*' )
aliases[tonumber(mw.ustring.match(tmp[1], '^[1-9][0-9]*$')) or tmp[1]] = ((tonumber(mw.ustring.match(tmp[2], '^[1-9][0-9]*$'))) or tmp[2])
end
end
for k, v in pairs( aliases ) do
if args[k] and ( not args[v] or args[v] == '' ) then
args[v] = args[k]
end
args[k] = nil
end
-- Remove empty parameters, if specified
if string.find( ','..(frame.args['$flags'] or '')..',', ',%s*remove%-empty%s*,' ) then
local tmp = 0
for k, v in ipairs( args ) do
if v ~= '' or ( args[k+1] and args[k+1] ~= '' ) or ( args[k+2] and args[k+2] ~= '' ) then
tmp = k
else
break
end
end
for k, v in pairs( args ) do
if v == '' then
if not (type(k) == 'number' and k < tmp) then args[k] = nil end
end
end
end
-- Order parameters
if frame.args['$params'] then
local params, tmp = mw.text.split( frame.args['$params'], '%s*,%s*' ), {}
for k, v in ipairs(params) do
v = tonumber(mw.ustring.match(v, '^[1-9][0-9]*$')) or v
if args[v] then tmp[v], args[v] = args[v], nil end
end
for k, v in pairs(args) do tmp[k], args[k] = args[k], nil end
args = tmp
end
return mTemplateInvocation.invocation(name, args)
end
p[''] = p.main -- For backwards compatibility
return p
66516cd1b82c9c1f13ac5cc5b9a87e1c93242068
Модуль:Dates
828
281
723
2021-10-11T18:35:23Z
ruwiki>Wikisaurus
0
параметр nolinks для отключения викификации даты в [[Модуль:Wikidata/date]]
Scribunto
text/plain
--[[
В это модуле собраны функции, связанные с работой с датами.
]]
local monthg = {'января', 'февраля', 'марта', 'апреля', 'мая', 'июня',
'июля', 'августа', "сентября", "октября", "ноября", "декабря"}
local monthd = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
local function DecodeDate(d)-- Ч, М, Г, СЧ, СМ, СГ, хвост
--дата: "%-?%d+"=год, "%d+%.%d+"=число месяца, "%d+%.%d+%.%-?%d+"=ЧМГ,
-- потом в скобках м.б. переопределено для старого стиля начиная с числа
local nd=d:match("^[%d.-]*");
local od=d:match("^[%d.-]*%s*%(%s*([%d.-]*)%s*%)");
local tail = d:match("^[%d.-]+%s*%(%s*[%d.-]+%s*%)%s*(%S.*)") or d:match("^[%d.-]+%s*([^%s%d].*)");
if nd:match('^%-?%d+$' ) then
return nil, nil, tonumber(nd), nil, nil, od and tonumber(od:match("%-?%d+$")),tail
else
local j,m,y=nd:match("^(%d+)%.(%d+)%.?(%-?%d*)");
if j then
if od then
local oj, om, oy = od:match("^(%d+)%.?(%d*)%.?(%-?%d*)");
return j and tonumber(j),
m and tonumber(m),
y>'' and tonumber(y) or nil,
oj and tonumber(oj),
om>'' and tonumber(om) or nil,
oy>'' and tonumber(oy) or nil,
tail
end
return j and tonumber(j), m and tonumber(m), y>'' and tonumber(y) or nil, nil, nil, nil, tail
else return nil
end
end
end
local function Diffy(d1,m1,y1,d0,m0,y0)--аналог Персона/Дата/Прошло лет
return y1-y0 - ( y1*y0<=0 and 1 or 0 ) - ( (m1<m0 or m1==m0 and d1<d0) and 1 or 0 )
end
local function Year0(y,t)-- аналог Год0
if y>0 then return table.concat{
'[[', tostring(y), ' год|', t and tostring(y)..' '..t or tostring(y), ']]'
} else return table.concat{
'[[', tostring(-y), ' год до н. э.|',
t and tostring(-y)..' '..t or tostring(-y),
' до н. э.]]'
}
end
end
local function FormDate(j,m,y,oj,om,oy,mo)-- ~ Персона/Дата/Logic 4
if j then
if not m then return "''формат неверен''" end
if y then return
string.format(
'<span class="nowrap">%s<span style="display:none">(<span class="%s">%04i-%02i-%02i</span>)</span></span>',
table.concat(
oj and (
om and (
oy and {-- ДД ММММ ГГГГ ([[ДД ММММ]] [[ГГГГ]])
oj,' ',monthg[om],' ',oy,
'</span> <span class="nowrap">([[',
j, ' ', monthg[m],']] ',Year0(y),')'
} or {-- ДД ММММ ([[ДД ММММ]]) [[ГГГГ]]
oj,' ',monthg[om],' ([[',j,' ',monthg[m],']]) ',Year0(y)
}
) or {-- ДД [[ДД ММММ|(ДД) ММММ]] [[ГГГГ]]
oj,' [[',j,' ',monthg[m],'|','(',j,') ',monthg[m],']] ',Year0(y)
}
) or {'[[',j,' ',monthg[m],']] ',Year0(y)}
),--/table.concat
({['Рождения']='bday',['Смерти']='dday'})[mo] or '',
y,m,j
)--/string.format
else return
'<span class="nowrap">' .. table.concat(
oj and (
om and {-- ДД ММММ ([[ДД ММММ]])
oj,' ',monthg[om],' ([[',j,' ',monthg[m],']])</span>'
} or {-- ДД [[ДД ММММ|(ДД) ММММ]]
oj,' [[',j,' ',monthg[m],'|','(',j,') ',monthg[m],']]</span>'
}
) or {'[[',j,' ',monthg[m],']]</span>'}
)
end
else
return y and string.format(
'<span class="nowrap">%s<span style="display:none;">(<span class="bday">%04i</span>)</span></span>',
Year0(y,'год'),y) or "''формат неверен''"
end
end
local function GetDate(D)--dd.mm.-?yyyy или -?yyyy-mm-dd в три переменных d,m,y
local d,m,y = d:match('^%s*(%d%d?)[/.]([01]?%d)[/.](%-?%d+)')
if not d then y,m,d = D:match('^%s*(%-?%d+)[-\\]0*(1?%d)[-\\]0*(%d+)') end
return tonumber(d),tonumber(m),tonumber(y)
end
local function Cmp(a,b)--Сравнивает две даты, результат соответственно -1, 0 или 1
local d1,m1,y1 = GetDate(a)
local d2,m2,y2 = GetDate(b)
return d1 and d2 and (--nil, если формат не опознан
y1==y2 and (
m1==m2 and (
d1==d2 and 0 or d1<d2 and -1 or 1
) or m1<m2 and -1 or 1
) or y1<y2 and -1 or 1
)
end
local function Yyyymmdd(r)--Переводит русскую дату в YYYY,MM,DD
local d, m, y, M = mw.ustring.match(r, "^%s*(%d%d?)%s+([а-яА-Я]+)%s+(%d+)")
if not m then return nil end
m = mw.ustring.lower(m)
--тупо перебор
for i = 1, 12 do
if m == monthg[i] then
M = i
break
end
end
if not M then
return nil
end
return tonumber(y), M, tonumber(d)
end
local p = {}
p = {
ifdate=function(f)-- Для шаблона "Если дата", имитирует старое поведение
-- Аргументы передаются шаблону
return f:getParent().args[ mw.ustring.match(frame.args[1],"^[ %d.%-−%()]*$") and 2 or 3 ]
end;
DecodeDate = DecodeDate;
Diffy = Diffy;
Year0 = Year0;
GetDate = GetDate;
Cmp = Cmp;
Yyyymmdd = Yyyymmdd;
diffy = function(f)-- принимает параметры #invoke в виде двух строк-дат
local d1,m1,y1=DecodeDate(f.args[1]);
local d0,m0,y0=DecodeDate(f.args[2])
return Diffy(d1,m1,y1,d0,m0,y0)
end;
monthg=function(f) return monthg[ f.args[1] or f:getParent().args[1] ] end;--realmonth
persdate=function(f)-- Для шаблона Персона/Дата;{{#invoke:dates|persdate|nocat={{NAMESPACE}}}}
local frame=f:getParent();
local catpref,mo,d,d2={['Рождения']='Родившиеся',['Смерти']='Умершие'}, frame.args[1],frame.args[2],frame.args[3]
local cat, j,m,y,oj,om,oy,tail, j2,m2,y2, age = ''
if d then
j,m,y,oj,om,oy,tail=DecodeDate(d:gsub('−','-'));
if not (j or y) then
return (frame.args.nocat and d or d..'[[Category:Википедия:Статьи с ручной викификацией дат в карточке]]')
end
end;
if d2 then
j2,m2,y2 = DecodeDate(d2:gsub('−','-'));
end;
return table.concat{
FormDate(j,m,y,oj,om,oy,mo),
( (frame.args['nopersoncat'] or '')~='' or (f.args['nocat'] or '')~='' ) and '' or table.concat{
'[[Category:Персоналии по алфавиту]]',
j and string.format('[[Category:%s %i %s]]',catpref[mo],j,monthg[m]) or '',
y and string.format('[[Category:%s в %s]]',catpref[mo],y,Year0(y,'году')) or ''
},--/table.concat внутр.
(function(F)--возраст
if not F then return '' end;
local n=F();
return n and string.format(" (%i %s)%s",
n,
mw.getLanguage('ru'):plural(n,'год','года','лет'),
n>150 and '[[Category:Википедия:Статьи о персоналиях с большим текущим возрастом]]' or ''
) or ''
end)( ({
['Рождения']=function()
local now=os.date('*t');
if (not d2 or d2=='') and j and m and y then
return Diffy(now.day,now.month,now.year,j,m,y)
end
end,
['Смерти']=function()
return j and m and y and j2 and m2 and y2 and Diffy(j,m,y,j2,m2,y2);
end,
})[mo] ),--конец вызова функции возраста
tail or '',
cat
}--/table.concat внеш.
end;
formdate=function(f) -- Формирует дату по 3--6 параметрам #invoke или шаблона
--не использовать с пустыми аргументами
if (f.args[1] or '')~='' and (f.args[2] or '')~='' or (f.args[3] or '')~='' then
return FormDate(f.args[1],f.args[2],f.args[3],f.args[4],f.args[5],f.args[6],f.args['m'])
else
local tf=f:getParent();
return FormDate(tf.args[1],tf.args[2],tf.args[3],tf.args[4],tf.args[5],tf.args[6],tf.args['m'])
end
end;
cmp=function(f)--Сравнивает две даты, результат соответственно -1, 0 или 1
return Cmp(f.args[1],f.args[2])
end;
G2J=function(f)--перевод григорианских дат в юлианские, возврат DD.MM.YYYY
--Не знает про 15 октября 1582 года, не работает до нашей эры и после ???99 года
--Если есть второй аргумент, преобразует только ДО этой даты включительно
--Если есть третий аргумент, результат форматирует под Персона/Дата
local d,m,y=GetDate(f.args[1])
if f.args[2] and Cmp(f.args[1],f.args[2])==1 then
return string.format("%i.%i.%i",d,m,y)
end
local shift=math.floor(y/100)-math.floor(y/400)-2
if d-shift>0 then
return f.args[3] and string.format("%i.%i.%i (%i)",d,m,y,d-shift)
or string.format("%i.%i.%i",d-shift,m,y)
else
if m==1 then
return f.args[3]
and string.format("%i.1.%i (%i.12.%i)",d,y,31+d-shift,y-1)
or string.format("%i.12.%i",31+d-shift,y-1)
elseif m==3 then
return f.args[3] and string.format("%i.3.%i (%i.2)", d,y,
(y%4==0 and 29 or 28)+d-shift-(y%100==0 and y%400~=0 and 1 or 0)
)
or string.format("%i.2.%i",
(y%4==0 and 29 or 28)+d-shift-(y%100==0 and y%400~=0 and 1 or 0)
,y)
else
return f.args[3] and string.format(
"%i.%i.%i (%i.%i)", d,m,y, monthd[m-1]+d-shift,m-1
)
or string.format("%i.%i.%i",monthd[m-1]+d-shift,m-1,y)
end
end
end;
-- Переводит русскую дату в YYYY-MM-DD. Возвращает входное значение, если дата уже в этом формате
yyyymmdd = function(f)
local date, hourmin = f.args[1]
if mw.ustring.match(date, "^%s*%d+\-%d+\-%d+") then
return date
end
hourmin = mw.ustring.match(date, "%s+%d+:%d+$")
local y, m, d = Yyyymmdd(date)
if not y then
return '<span class="error">Ошибка: некорректный формат даты.</span>'
end
return string.format('%4i-%02i-%02i', y, m, d) .. (hourmin or '')
end
}
function table.val_to_str ( v )
if "string" == type( v ) then
v = string.gsub( v, "\n", "\\n" )
if string.match( string.gsub(v,"[^'\"]",""), '^"+$' ) then
return "'" .. v .. "'"
end
return '"' .. string.gsub(v,'"', '\\"' ) .. '"'
else
return "table" == type( v ) and table.tostring( v ) or
tostring( v )
end
end
function table.key_to_str ( k )
if "string" == type( k ) and string.match( k, "^[_%a][_%a%d]*$" ) then
return k
else
return "[" .. table.val_to_str( k ) .. "]"
end
end
function table.tostring( tbl )
local result, done = {}, {}
for k, v in ipairs( tbl ) do
table.insert( result, table.val_to_str( v ) )
done[ k ] = true
end
for k, v in pairs( tbl ) do
if not done[ k ] then
table.insert( result,
table.key_to_str( k ) .. "=" .. table.val_to_str( v ) )
end
end
return "{" .. table.concat( result, "," ) .. "}"
end
local function parseISO8601Date(str)
local pattern = "(%-?%d+)%-(%d+)%-(%d+)T"
local Y, M, D = mw.ustring.match( str, pattern )
return tonumber(Y), tonumber(M), tonumber(D)
end
local function parseISO8601Time(str)
local pattern = "T(%d+):(%d+):(%d+)%Z"
local H, M, S = mw.ustring.match( str, pattern)
return tonumber(H), tonumber(M), tonumber(S)
end
local function parseISO8601Offset(str)
if str:sub(-1)=="Z" then return 0,0 end -- ends with Z, Zulu time
-- matches ±hh:mm, ±hhmm or ±hh; else returns nils
local pattern = "([-+])(%d%d):?(%d?%d?)$"
local sign, oh, om = mw.ustring.match( str, pattern)
sign, oh, om = sign or "+", oh or "00", om or "00"
return tonumber(sign .. oh), tonumber(sign .. om)
end
function p.parseISO8601(str)
if 'table'==type(str) then
if str.args and str.args[1] then
str = '' .. str.args[1]
else
return 'unknown argument type: ' .. type( str ) .. ': ' .. table.tostring( str )
end
end
local Y,M,D = parseISO8601Date(str)
local h,m,s = parseISO8601Time(str)
local oh,om = parseISO8601Offset(str)
return tonumber(os.time({year=Y, month=M, day=D, hour=(h+oh), min=(m+om), sec=s}))
end
local g2uBoundary1 = p.parseISO8601('1582-10-15T00:00:00Z')
local g2uBoundary2 = p.parseISO8601('1700-03-12T00:00:00Z')
local g2uBoundary3 = p.parseISO8601('1800-03-13T00:00:00Z')
local g2uBoundary4 = p.parseISO8601('1900-03-14T00:00:00Z')
local g2uBoundary5 = p.parseISO8601('1918-01-26T00:00:00Z') -- декрет Ленина
-- Передаваемое время обязано быть по Григорианскому календарю (новому стилю)
function p.formatWiki( time, infocardClass, categoryNamePrefix )
if 'table'==type( time ) then
if time.args and time.args[1] then
time = tonumber( time.args[1] )
else
return 'unknown argument type: ' .. type( time ) .. ': ' .. table.tostring( time )
end
end
local t = os.date("*t", time)
if time < g2uBoundary1 then
-- выводим просто юлианский календарь. Задавать тут григорианский некорректно
return p.formatWikiImpl( t, t, infocardClass, categoryNamePrefix )
end
-- Специальные даты
if t.year == 1700 and t.month == 3 and t.day == 11 then
return p.formatWikiImpl( {year=1700, month=2, day=29}, t, infocardClass, categoryNamePrefix)
end
if t.year == 1800 and t.month == 3 and t.day == 12 then
return p.formatWikiImpl( {year=1800, month=2, day=29}, t, infocardClass, categoryNamePrefix )
end
if t.year == 1900 and t.month == 3 and t.day == 13 then
return p.formatWikiImpl( {year=1900, month=2, day=29}, t, infocardClass, categoryNamePrefix )
end
if g2uBoundary1 <= time and time < g2uBoundary2 then
return p.formatWikiImpl( os.date("*t", time - 10 * 24 * 60 * 60), t, infocardClass, categoryNamePrefix )
end
if g2uBoundary2 <= time and time < g2uBoundary3 then
return p.formatWikiImpl( os.date("*t", time - 11 * 24 * 60 * 60), t, infocardClass, categoryNamePrefix )
end
if g2uBoundary3 <= time and time < g2uBoundary4 then
return p.formatWikiImpl( os.date("*t", time - 12 * 24 * 60 * 60), t, infocardClass, categoryNamePrefix )
end
if g2uBoundary4 <= time and time < g2uBoundary5 then
return p.formatWikiImpl( os.date("*t", time - 13 * 24 * 60 * 60), t, infocardClass, categoryNamePrefix )
end
--только Григорианский календарь
return p.formatWikiImpl( t, t, infocardClass, categoryNamePrefix )
end
local function ternary ( cond , T , F )
if cond then return T else return F end
end
local nominativeMonthes = {'январь', 'февраль', 'март', 'апрель', 'май', 'июнь',
'июль', 'август', 'сентябрь', 'октябрь', 'ноябрь', 'декабрь'}
local genitivusMonthes = {'января', 'февраля', 'марта', 'апреля', 'мая', 'июня',
'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря'}
local function nominativeYear( year, nolinks )
if ( year >= 0 ) then
return nolinks and year or '[[' .. year .. ' год|' .. year .. ']]'
else
return nolinks and ( 0 - year ) .. ' до н. э.' or '[[' .. ( 0 - year ) .. ' год до н. э.|' .. ( 0 - year ) .. ' до н. э.]]'
end
end
local function inYear( year )
if ( year >= 0 ) then
return '' .. year .. ' году'
else
return '' .. ( 0 - year) .. ' году до н. э.'
end
end
function p.formatWikiImpl( t1, t2, infocardClass, categoryNamePrefix, leftBracket, rightBracket, nolinks )
local nd = t2.day;
local nm = t2.month;
local ny = t2.year;
local od = ternary ( t1.day ~= t2.day , t1.day, nil );
local om = ternary ( t1.month ~= t2.month , t1.month, nil );
local oy = ternary ( t1.year ~= t2.year , t1.year, nil );
if leftBracket == nil then
leftBracket = '('
end
if rightBracket == nil then
rightBracket = ')'
end
local JulianComment = function(s)
return tostring(mw.html.create("abbr")
:attr("title","по юлианскому календарю")
:wikitext(s)
:done())
end
local template =
(nd ~= nil and "1" or "") .. (nm ~= nil and "2" or "") .. (ny ~= nil and "3" or "") ..
(od ~= nil and "4" or "") .. (om ~= nil and "5" or "") .. (oy ~= nil and "6" or "")
local datePart = '<span class="nowrap">'
if (template == "12") then
datePart = datePart .. string.format( nolinks and "%d %s" or "[[%d %s]]",
nd, genitivusMonthes[nm] )
elseif (template == "23") then
datePart = datePart .. string.format( "%s %s",
nominativeMonthes[nm], nominativeYear( ny, nolinks ) )
elseif (template == "3") then
datePart = datePart .. nominativeYear( ny, nolinks )
elseif (template == "123") then
datePart = datePart .. string.format( nolinks and "%d %s %s" or "[[%d %s]] %s",
nd, genitivusMonthes[nm], nominativeYear( ny, nolinks ) )
elseif (template == "124") then
if nolinks then
datePart = datePart .. JulianComment(string.format( "%d", od )
).. string.format( " " .. leftBracket .. "%d" .. rightBracket .. " %s",
nd, genitivusMonthes[nm] )
else
datePart = datePart .. JulianComment(string.format( "%d", od )
).. string.format( " [[%d %s|" .. leftBracket .. "%d" .. rightBracket .. " %s]]",
nd, genitivusMonthes[nm], nd, genitivusMonthes[nm] )
end
elseif (template == "1234") then
if nolinks then
datePart = datePart .. JulianComment(string.format( "%d", od )
).. string.format( " |" .. leftBracket .. "%d" .. rightBracket .. " %s %s",
nd, genitivusMonthes[nm], nominativeYear( ny, nolinks ) )
else
datePart = datePart .. JulianComment(string.format( "%d", od )
).. string.format( " [[%d %s|" .. leftBracket .. "%d" .. rightBracket .. " %s]] %s",
nd, genitivusMonthes[nm], nd, genitivusMonthes[nm], nominativeYear( ny, nolinks ) )
end
elseif (template == "1245") then
datePart = datePart .. JulianComment(string.format( "%d %s", od, genitivusMonthes[om] )
).. string.format(" " .. leftBracket .. (nolinks and "%d %s" or "[[%d %s]]") .. rightBracket .. "", nd, genitivusMonthes[nm] )
elseif (template == "12345") then
datePart = datePart .. JulianComment(string.format( "%d %s", od, genitivusMonthes[om] )
).. string.format(" " .. leftBracket .. (nolinks and "%d %s" or "[[%d %s]]") .. rightBracket .. " %s", nd, genitivusMonthes[nm], nominativeYear( ny, nolinks ) )
elseif (template == "123456") then
datePart = datePart .. JulianComment(string.format( "%d %s %d", od, genitivusMonthes[om], oy ))
.. '</span> <span class="nowrap">'
.. string.format(" " .. leftBracket .. (nolinks and "%d %s %s" or "[[%d %s]] %s") .. rightBracket , nd, genitivusMonthes[nm], nominativeYear( ny, nolinks ) )
else
datePart = datePart .. 'формат неверен'
end
datePart = datePart .. '</span>'
local infocardTemplate =
(nd ~= nil and "1" or "") .. (nm ~= nil and "2" or "") .. (ny ~= nil and "3" or "")
if infocardClass then
if (infocardTemplate == "123") then
datePart = datePart .. string.format('<span style="display:none">(<span class="%s">%04d-%02d-%02d</span>)</span>', infocardClass , ny , nm , nd )
elseif (infocardTemplate == "23") then
datePart = datePart .. string.format('<span style="display:none">(<span class="%s">%04d-%02d</span>)</span>', infocardClass , ny , nm )
elseif (infocardTemplate == "3") then
datePart = datePart .. string.format('<span style="display:none;">(<span class="%s">%04d</span>)</span>', infocardClass , ny )
end
end
if categoryNamePrefix then
if ( nd ~= nil and nm ~= nil) then
datePart = datePart .. '[[Category:' .. categoryNamePrefix .. ' ' .. nd .. ' ' .. genitivusMonthes[nm] .. ']]'
end
if ( ny ~= nil) then
datePart = datePart .. '[[Category:' .. categoryNamePrefix .. ' в ' .. inYear( ny ) .. ']]'
end
end
return datePart
end
return p
902bb6a9ef5ce12ad4cfa19f3d2c964d7e092df7
Шаблон:Орден Красного Знамени
10
289
739
2021-10-23T21:05:30Z
ruwiki>Jack who built the house
0
оформление кода при помощи [[u:JWBTH/CP|скрипта]]
wikitext
text/x-wiki
{{#switch: {{{тип|}}}
| воинская часть = [[Файл:Order of Red Banner.svg|34px|link=Орден Красного Знамени|Орден Красного Знамени {{#if: {{{1|}}} | — {{{1}}} }}]]{{#if: {{NAMESPACE}}{{{nocat|}}} || [[Категория:Воинские части, награждённые орденом Красного Знамени]] }}
| город = [[Файл:Order of Red Banner.svg|34px|link=Орден Красного Знамени|Орден Красного Знамени{{#if: {{{1|}}} | — {{{1}}} }}]]{{#if: {{NAMESPACE}}{{{nocat|}}} || [[Категория:Города, награждённые орденом Красного Знамени]] }}
| регион = [[Файл:Order of Red Banner.svg|34px|link=Орден Красного Знамени|Орден Красного Знамени{{#if: {{{1|}}} | — {{{1}}} }}]]{{#if: {{NAMESPACE}}{{{nocat|}}} || [[Категория:Регионы, награждённые орденом Красного Знамени]] }}
| организация = [[Файл:Order of Red Banner.svg|34px|link=Орден Красного Знамени|Орден Красного Знамени{{#if: {{{1|}}} | — {{{1}}} }}]]{{#if: {{NAMESPACE}}{{{nocat|}}} || [[Категория:Организации, награждённые орденом Красного Знамени]] }}
| СМИ | сми = [[Файл:Order of Red Banner.svg|34px|link=Орден Красного Знамени|Орден Красного Знамени {{#if: {{{1|}}} | — {{{1}}} }}]]{{#if: {{NAMESPACE}}{{{nocat|}}} || [[Категория:СМИ, награждённые орденом Красного Знамени]] }}
| корабль = [[Файл:Order of Red Banner.svg|34px|link=Орден Красного Знамени|Орден Красного Знамени{{#if: {{{1|}}} | — {{{1}}} }}]]{{#if: {{NAMESPACE}}{{{nocat|}}} || [[Категория:Корабли, награждённые орденом Красного Знамени]] }} | [[Файл:SU Order of the Red Banner ribbon.svg|40px|link=Орден Красного Знамени|Орден Красного Знамени {{#if: {{{1|}}} | — {{{1}}} }}]]{{#if: {{NAMESPACE}}{{{nocat|}}} || [[Категория:Кавалеры ордена Красного Знамени]] }}
}}<noinclude>
{{doc}}
</noinclude>
a4b6026ef99495ca5077c93a9192ac2427bbb09e
Шаблон:Doc
10
171
384
2021-10-24T00:40:31Z
ruwiki>Jack who built the house
0
оформление кода при помощи [[u:JWBTH/CP|скрипта]]
wikitext
text/x-wiki
<includeonly>{{doc/begin|{{SUBJECTSPACE}}:{{PAGENAME:{{{1|{{SUBJECTPAGENAME}}/doc}}}}}}}
{{#if: {{{1|}}}
| {{#ifexist: {{{1}}}
| {{{{{1}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}|{{{5|}}}}}
| {{#ifexist: {{SUBJECTSPACE}}:{{{1}}}
| {{{{{1}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}|{{{5|}}}}}
| {{Документировать|{{{1}}}}}
}}
}}
| {{#ifexist: {{SUBJECTPAGENAME}}/doc
| {{{{SUBJECTPAGENAME}}/doc}}
| {{Документировать|{{SUBJECTPAGENAME}}/doc}}
}}
}}
{{doc/end}}</includeonly><noinclude>
{{doc}}
</noinclude>
391c7f0f075319e6b3305557c55e98c581696c71
Шаблон:Карточка/блок с маркерами
10
156
354
2021-10-24T15:48:39Z
ruwiki>Oleg Yunakov
0
Защитил страницу [[Шаблон:Карточка/блок с маркерами]]: критический шаблон или модуль: https://ru.wikipedia.org/w/index.php?title=Википедия:Установка_защиты&oldid=117401039#Шаблоны ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно))
wikitext
text/x-wiki
{{#invoke:Infobox/bulleted block|main}}<noinclude>{{doc}}</noinclude>
71e7755aa4fb1e445f008da13d6fa4212aea3c38
Шаблон:Орден Октябрьской Революции
10
294
749
2021-10-24T15:52:04Z
ruwiki>Oleg Yunakov
0
Изменил настройки защиты для «[[Шаблон:Орден Октябрьской Революции]]»: критический шаблон или модуль: https://ru.wikipedia.org/w/index.php?title=Википедия:Установка_защиты&oldid=117401039#Шаблоны ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно))
wikitext
text/x-wiki
{{#switch: {{{тип|}}}
| воинская часть = [[Файл:Order of the October Revolution.svg|45px|link=Орден Октябрьской Революции|Орден Октябрьской Революции {{#if: {{{1|}}}| — {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Воинские части, награждённые орденом Октябрьской Революции]]}}
| город = [[Файл:Order of the October Revolution.svg|45px|link=Орден Октябрьской Революции|Орден Октябрьской Революции {{#if: {{{1|}}}| — {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Города, награждённые орденом Октябрьской Революции]]}}
| регион = [[Файл:Order of the October Revolution.svg|45px|link=Орден Октябрьской Революции|Орден Октябрьской Революции {{#if: {{{1|}}}| — {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Регионы, награждённые орденом Октябрьской Революции]]}}
| организация = [[Файл:Order of the October Revolution.svg|45px|link=Орден Октябрьской Революции|Орден Октябрьской Революции {{#if: {{{1|}}}| — {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Организации, награждённые орденом Октябрьской Революции]]}}
| СМИ | сми = [[Файл:Order of the October Revolution.svg|45px|link=Орден Октябрьской Революции|Орден Октябрьской Революции {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:СМИ, награждённые орденом Октябрьской Революции]]}}
| корабль = [[Файл:Order of the October Revolution.svg|45px|link=Орден Октябрьской Революции|Орден Октябрьской Революции {{#if: {{{1|}}}| — {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Корабли, награждённые орденом Октябрьской Революции]]}}
| [[Файл:SU Order of the October Revolution ribbon.svg|40px|link=Орден Октябрьской Революции|Орден Октябрьской Революции {{#if: {{{1|}}}| — {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Кавалеры ордена Октябрьской Революции]]}}
}}<noinclude>
{{doc}}
</noinclude>
c58fd2bbb6f2eea7bf65e4206a596693f9307c98
Шаблон:Ряд/styles.css
10
291
743
2021-10-24T16:01:25Z
ruwiki>Oleg Yunakov
0
Защитил страницу [[Шаблон:Ряд/styles.css]]: критический шаблон или модуль: https://ru.wikipedia.org/w/index.php?title=Википедия:Установка_защиты&oldid=117401039#Шаблоны + Было бы неплохо и документацию потом добавить ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно))
sanitized-css
text/css
.ts-Ряд {
width: auto;
border-collapse: collapse;
}
.ts-Ряд td {
padding-right: 2px;
padding-left: 2px;
text-align: center;
}
.ts-Ряд td:first-child {
padding-left: 0;
text-align: left;
}
.ts-Ряд td:last-child {
padding-right: 0;
text-align:right;
}
.ts-Ряд.pull-left {
}
.ts-Ряд.pull-center {
margin: 0 auto !important;
}
.ts-Ряд.pull-right {
clear: right;
margin: 0 0 0 auto !important;
}
.ts-Ряд.pull-justify {
width: 100%;
}
body.skin-minerva .ts-Ряд {
display: table;
}
body.skin-minerva .ts-Ряд td {
padding: 2px;
}
body.skin-minerva .ts-Ряд:not(.pull-justify) {
width: auto !important;
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
2229c228f5137296027e241d85449ea3d3a02656
Шаблон:Ряд
10
290
741
2021-10-24T17:09:43Z
ruwiki>Oleg Yunakov
0
Защитил страницу [[Шаблон:Ряд]]: критический шаблон или модуль: https://ru.wikipedia.org/w/index.php?title=Википедия:Установка_защиты&oldid=117401039#Шаблоны ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно))
wikitext
text/x-wiki
<templatestyles src="Шаблон:Ряд/styles.css" /><table role="presentation" class="infobox-inherit ts-Ряд {{#switch:{{{выровнять|}}}
| влево = pull-left
| вправо = pull-right
| по ширине = pull-justify
| #default = pull-center}}"><tr>{{
#if:{{{1|}}}|<td>{{{1}}}</td>}}{{
#if:{{{2|}}}|<td>{{{2}}}</td>}}{{
#if:{{{3|}}}|<td>{{{3}}}</td>}}{{
#if:{{{4|}}}|<td>{{{4}}}</td>}}{{
#if:{{{5|}}}|<td>{{{5}}}</td>}}{{
#if:{{{6|}}}|<td>{{{6}}}</td>}}{{
#if:{{{7|}}}|<td>{{{7}}}</td>}}{{
#if:{{{8|}}}|<td>{{{8}}}</td>}}{{
#if:{{{9|}}}|<td>{{{9}}}</td>}}{{
#if:{{{10|}}}|<td>{{{10}}}</td>}}
</tr></table><noinclude>{{doc}}</noinclude>
387ead03289de2d203805d43b37873225d7eaa75
Шаблон:Ombox
10
20
424
2021-10-24T18:05:30Z
ruwiki>Oleg Yunakov
0
Изменил настройки защиты для «[[Шаблон:Ombox]]»: критический шаблон или модуль: https://ru.wikipedia.org/w/index.php?title=Википедия:Установка_защиты&oldid=117401039#Шаблоны ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно))
wikitext
text/x-wiki
{{#invoke:Message box|ombox}}<noinclude>
{{doc}}<!-- Add categories and interwikis to the /doc subpage, not here! --></noinclude>
ab34435c5ebc29de589c9b059e88da5d0e6f16e4
Модуль:Infobox/bulleted block
828
159
360
2021-10-24T18:17:22Z
ruwiki>Oleg Yunakov
0
Защитил страницу [[Модуль:Infobox/bulleted block]]: критический шаблон или модуль: https://ru.wikipedia.org/w/index.php?title=Википедия:Установка_защиты&oldid=117401039#Шаблоны ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно))
Scribunto
text/plain
local p = {}
-- takes strings or nils; returns a string
function makeText(frame, text, wikidata, from)
if wikidata and wikidata ~= ''then
return frame:expandTemplate{title='Wikidata', args={wikidata, text or '', from=from or ''}}
else
return text or ''
end
end
-- from [[ru:Модуль:Infobox]]
local function maxNumber ( args )
local maxNumber = 0
for argName, _ in pairs(args) do
local argNumber = mw.ustring.match(argName, '^[^0-9]+([0-9]+)$')
if argNumber and tonumber(argNumber) > maxNumber then
maxNumber = tonumber(argNumber)
end
end
return maxNumber
end
function p.main(frame)
local args = frame:getParent().args
local maxNumberArgs = maxNumber(args)
local texts = {}
for i = 1, maxNumberArgs do
if args['текст' .. i] then
texts[i] = makeText(frame, args['текст' .. i], args['викиданные' .. i], args['from'])
end
end
local textsAreEmpty = true
for i = 1, maxNumberArgs do
if texts[i] and texts[i] ~= '' then
textsAreEmpty = false
end
end
local results = {}
if not textsAreEmpty and args['подзаголовок'] and args['подзаголовок'] ~= '' then
results['текст1'] = args['подзаголовок']
results['стиль_текста1'] = 'padding-bottom:0; border-bottom:0; text-align:left; font-weight:bold;'
end
local mainText = makeText(frame, args['текст'], args['викиданные'], args['from'])
if mainText == '' and args['метка'] and args['метка'] ~= '' and not textsAreEmpty then
mainText = ' '
end
if mainText and mainText ~= '' then
results['метка2'] = args['метка']
results['стиль_метки2'] = 'padding-bottom:0; border-bottom:0;'
results['текст2'] = mainText
results['стиль_текста2'] = 'padding-bottom:0; border-bottom:0;'
end
for i = 1, maxNumberArgs do
if texts[i] and texts[i] ~= '' then
results['метка' .. (i+2)] = ' • ' .. (args['метка' .. i] or '')
results['текст' .. (i+2)] = texts[i]
local last = true
for j = i+1, maxNumberArgs do
if texts[j] and texts[j] ~= '' then
last = false
end
end
if last then
results['стиль_метки' .. (i+2)] = 'font-weight:normal; padding-top:0; border-top:0;'
results['стиль_текста' .. (i+2)] = 'padding-top:0; border-top:0;'
else
results['стиль_метки' .. (i+2)] = 'font-weight:normal; padding-bottom:0; border-bottom:0; padding-top:0; border-top:0;'
results['стиль_текста' .. (i+2)] = 'padding-bottom:0; border-bottom:0; padding-top:0; border-top:0;'
end
end
end
return frame:expandTemplate{title='Карточка/блок', args=results}
end
return p
856b97606e1f2809c940e384f6fe71a575ca019e
Шаблон:Tlp
10
217
482
2021-10-24T18:18:30Z
ruwiki>Oleg Yunakov
0
Изменил настройки защиты для «[[Шаблон:Tlp]]»: критический шаблон или модуль: https://ru.wikipedia.org/w/index.php?title=Википедия:Установка_защиты&oldid=117401039#Шаблоны ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно))
wikitext
text/x-wiki
{{{{{|safesubst:}}}#invoke: Template call code | withParams | _link = 1 }}<noinclude>{{doc}}</noinclude>
36c309cb28ccf0901f4fff46cbd35cdabcf00661
Шаблон:Tag
10
72
116
2021-10-26T15:10:39Z
ruwiki>Jack who built the house
0
стилизация на основе [[Модуль:Template call code/styles.css]]
wikitext
text/x-wiki
{{#ifeq: {{{style|}}} | regular | <templatestyles src="Модуль:Template call code/styles.css" /> }}<{{#ifeq: {{{style|}}} | regular | span | code }} class="{{#ifeq: {{{wrap|}}} | yes | wrap | nowrap }}" style="{{#switch: {{{style|}}}
| plain = border:none; background:transparent;
| regular =
| {{{style|}}}
}}"><!--
Opening tag
-->{{#switch: {{#if: {{{2|}}} | {{{2|}}} | pair }}
|c|close =
|s|single
|o|open
|p|pair = {{#ifeq: {{{1|tag}}}
| !--
| {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak"><!--</span> | <!-- }}
| {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak"><</span> | < }}{{{1|tag}}}{{#if: {{{params|{{{p|}}}}}} |  {{{params|{{{p|}}}}}} }}
}}
}}<!--
Content between tags
-->{{#switch: {{#if: {{{2|}}} | {{{2|}}} | pair }}
|c|close = {{{content|{{{c|}}}}}}
|s|single =  {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">/></span> | /> }}
|o|open = {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">></span> | > }}{{{content|{{{c|}}}}}}
|p|pair = {{#ifeq: {{{1|tag}}} | !-- || {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">></span> | > }} }}{{{content|{{{c|}}}}}}
}}<!--
Closing tag
-->{{#switch: {{#if: {{{2|}}} | {{{2|}}} | pair }}
|s|single
|o|open =
|c|close
|p|pair = {{#ifeq: {{{1|tag}}}
| !--
| {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">--></span> | --> }}
| {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak"></</span>{{{1|tag}}}<span class="ts-templateCallCode-weak">></span> | </{{{1|tag}}}> }}
}}
}}<!--
--></{{#ifeq: {{{style|}}} | regular | span | code }}><noinclude>{{doc}}</noinclude>
2818843691a5275eaf013ee7cc1ac4b87c34f392
Модуль:Template call code
828
126
294
2021-10-26T19:03:06Z
ruwiki>Jack who built the house
0
-избыточный код
Scribunto
text/plain
local getArgs = require('Module:Arguments').getArgs
local ru = mw.language.new('ru')
local p = {}
-- Используется для того, чтобы можно было удалять элементы из таблицы
local function copy(other)
local res = {}
for k, v in pairs(other) do
res[k] = v
end
return res
end
local function makeInvokeFunc(funcName, flags)
return function (frame)
local args = copy(getArgs(frame, {
trim = false,
removeBlanks = false
}))
return p[funcName](args, flags)
end
end
--предотвращает обработку вики-текста в отображении образца
local function processText(str, nowiki)
local res = str
if nowiki then
str = mw.text.unstripNoWiki(str)
str = string.gsub(str, '%[', '[')
str = string.gsub(str, '%]', ']')
str = string.gsub(str, '<', '<')
str = string.gsub(str, '>', '>')
str = string.gsub(str, '{', '{')
str = string.gsub(str, '|', '|')
str = string.gsub(str, '}', '}')
str = string.gsub(str, '\'', ''')
str = string.gsub(str, '"', '"')
str = string.gsub(str, '(://)', '<span>%1</span>')
end
return str
end
local function addParams(args, params)
local text, equals_pos, param, value = '', 0, '', ''
local function addPipe()
if params.spaced then
text = text .. ' '
end
text = text .. '<span class="'
if not params.spaced then
text = text .. ' ts-templateCallCode-pipe'
end
if not params.black then
text = text .. ' ts-templateCallCode-weak'
end
-- |, чтобы не трактовалось как разделитель ячеек в таблицах
text = text .. '">|</span>'
end
local beforeParam = '<span class="ts-templateCallCode-param">'
local afterParam = '</span>'
for k, v in pairs(args) do
if type(k) == 'number' then -- Неименованные параметры
if k >= params.from then
equals_pos = v:find('=')
if equals_pos and v:find('{{=}}') == equals_pos - 2 then
equals_pos = nil
end
if equals_pos then -- Содержащие «=» преобразуем в именованные
param = v:sub(1, equals_pos - 1)
value = v:sub(equals_pos + 1)
addPipe()
text = text .. beforeParam .. processText(param, params.nowiki) .. '=' .. processText(value, params.nowiki) .. afterParam
else -- Истинно неименованные
addPipe()
local paramValue = processText(v, params.nowiki)
if #paramValue ~= 0 then
text = text .. beforeParam .. paramValue .. afterParam
end
end
end
elseif not k:find('^_') then -- Именованные параметры, исключая модификаторы внешнего вида
addPipe()
text = text .. beforeParam .. processText(k, params.nowiki) .. '=' .. processText(v, params.nowiki) .. afterParam
end
end
return text
end
function p._main(args, flags)
local name = args[1]
table.remove(args, 1)
-- Вещи типа «=» в первом параметре
if not name then
for k, v in pairs(args) do
if not k:find('^_') then
name = k .. '=' .. v
args[k] = nil
break
end
end
end
local optpText
if not flags.withoutParams then
if name then
local spanOffset = mw.ustring.find(name, '<span') -- След использования шаблона optp
if spanOffset then
optpText = mw.ustring.sub(name, spanOffset)
name = mw.ustring.sub(name, 1, spanOffset - 1)
end
end
end
local yesno = require('Module:Yesno')
local nolink, subst, podst, global, nav, noRedirect, ucFirst, black, nobr
local tag, style, comment, lang, sister, global, textInPlaceOfName,
namePrefix, prefix, postfix, nowiki
local spaced, from
if flags.withoutParams then
for i, v in ipairs(args) do
if v == 'nl' or v == 'nolink' then
noLink = true
elseif v == 's' then
subst = true
elseif v == 'п' then
podst = true
elseif v == 'g' then
global = true
elseif v == 'nav' then
nav = true
elseif v == 'noredir' then
noRedirect = true
elseif v == 'u' then
ucFirst = true
elseif v == 'b' then
black = true
elseif v == 'nobr' then
nobr = true
end
end
tag = args.tag or 'span'
style = args.style
comment = args.comment
lang = args.lang
sister = args.sister
textInPlaceOfName = args.text
namePrefix = args.nameprefix
prefix = args.prefix
postfix = args.postfix
nowiki = args.nowiki
else
noLink = yesno(args._nolink or args._nl, false) or not yesno(args._link, false)
subst = yesno(args._s, false)
podst = yesno(args['_п'], false)
global = yesno(args._g, false)
nav = yesno(args._nav, false)
noRedirect = yesno(args._noredir, false)
ucFirst = yesno(args._u, false)
black = yesno(args._b, false)
nobr = yesno(args._nobr, false)
tag = args._tag or 'span'
style = args._style
comment = args._comment
lang = args._lang
sister = args._sister
textInPlaceOfName = args._text
namePrefix = args._nameprefix
prefix = args._prefix
postfix = args._postfix
nowiki = args._nowiki
spaced = yesno(args._spaced, false)
from = (tonumber(args._from) or 2) - 1
end
global = global or name and mw.ustring.sub(name, 1, 1) == ':'
black = black or tag ~= 'span'
if textInPlaceOfName == '' then
textInPlaceOfName = nil
end
if comment == '' then
comment = nil
end
if lang == '' then
lang = nil
end
if sister == '' then
sister = nil
end
if namePrefix == '' then
namePrefix = nil
end
if name then
local trimmedName = mw.text.trim(name)
if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'subst:' then
subst = true
name = mw.ustring.sub(trimmedName, 7)
end
if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'подст:' then
podst = true
name = mw.ustring.sub(trimmedName, 7)
end
end
if subst then
namePrefix = 'subst:'
elseif podst then
namePrefix = 'подст:'
end
local currentTitle = mw.title.getCurrentTitle()
-- При опущенном первом параметре берём имя шаблона из названия страницы
if name == '' or not name then
local currentTitleRoot = currentTitle.rootText
if not ucFirst and
(
(
ru:uc(currentTitleRoot) ~= currentTitleRoot and
-- Книга:Литературное наследство, TranslateDate
not mw.ustring.match(currentTitleRoot, '^[А-Яа-яA-Za-z]+:?[А-ЯA-Z]')
) or
#currentTitleRoot == 1
)
then
name = ru:lcfirst(currentTitleRoot)
else
name = currentTitleRoot
end
end
-- Начинаем собирать код
local linkBody, titleObject, linkBegin, linkDivider, linkEnd
local prefixes = {}
if lang then
table.insert(prefixes, lang)
end
if sister then
table.insert(prefixes, sister)
end
linkBody = table.concat(prefixes, ':')
if #linkBody ~= 0 then
linkBody = ':' .. linkBody
end
if mw.ustring.sub(name, 1, 1) ~= ':' then
linkBody = linkBody .. ':'
end
if not global then
linkBody = linkBody .. 'Template:'
end
linkBody = linkBody .. name
titleObject = mw.title.new(linkBody)
local noLink = noLink or currentTitle == titleObject
if not noLink then
if not noRedirect or (
noRedirect and
not lang and
not sister and
not titleObject.exists
) then
linkBegin = '[['
linkEnd = ']]'
linkDivider = '|'
else
linkBegin = '['
linkEnd = ']'
linkDivider = ' '
linkBody = titleObject:fullUrl('redirect=no')
end
end
local text = ''
if tag then
text = text .. '<' .. tag .. ' class="ts-templateCallCode'
if nobr then
text = text .. ' nowrap'
end
text = text .. '"'
if style then
text = text .. ' style="' .. style .. '"'
end
text = text .. '>'
end
if prefix then
text = text .. processText(prefix, nowiki)
end
text = text .. '<span class="'
if not spaced then
text = text .. ' ts-templateCallCode-opening'
end
if not black then
text = text .. ' ts-templateCallCode-weak'
end
text = text .. '">{{'
if namePrefix then
text = text .. namePrefix
end
text = text .. '</span>'
if nav and currentTitle == titleObject then
text = text .. '\'\'\''
end
text = text .. '<span class="ts-templateCallCode-templateName" data-navboxnavigation-link="0">'
local commentedLabel
if comment then
-- https://phabricator.wikimedia.org/T200704
-- commentedLabel = mw.getCurrentFrame():expandTemplate({title = 'comment', args = {(textInPlaceOfName or name), comment}})
commentedLabel = '<span class="commentedText" title="' .. comment .. '" style="border-bottom: 1px dotted; cursor: help;">' ..
(textInPlaceOfName or name) ..
'</span>'
end
local label = (commentedLabel or textInPlaceOfName or name)
if not noLink then
if noRedirect then
text = text .. '<span class="plainlinks">'
end
text = text .. linkBegin .. linkBody .. linkDivider .. label .. linkEnd
if noRedirect then
text = text .. '</span>'
end
else
text = text .. label
end
text = text .. '</span>'
if nav and currentTitle == titleObject then
text = text .. '\'\'\''
end
if not flags.withoutParams then
if optpText then
text = text .. optpText
end
text = text .. addParams(args, {
spaced = spaced,
black = black,
nowiki = nowiki,
from = from
})
if spaced then
text = text .. ' '
end
end
text = text .. '<span class="'
if not spaced then
text = text .. ' ts-templateCallCode-closing'
end
if not black then
text = text .. ' ts-templateCallCode-weak'
end
text = text .. '">}}</span>'
if postfix then
text = text .. processText(postfix, nowiki)
end
if tag then
text = text .. '</' .. tag .. '>'
end
local ts = mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = { src = 'Модуль:Template call code/styles.css' } }
return ts .. text
end
function p._onlyParams(args)
local yesno = require('Module:Yesno')
return addParams(args, {
spaced = yesno(args._spaced, false),
black = true,
nowiki = yesno(args._nowiki, false),
from = 1
})
end
p.withoutParams = makeInvokeFunc('_main', {withoutParams = true})
p.withParams = makeInvokeFunc('_main', {withoutParams = false})
p.onlyParams = makeInvokeFunc('_onlyParams')
return p
c4cde66869b509219e9bf629a766ce30ad0bdf97
Шаблон:TOC right
10
194
434
2021-10-27T21:30:30Z
ruwiki>Grain of sand
0
TOC limit через TS
wikitext
text/x-wiki
<templatestyles src="Шаблон:TOC right/styles.css" /><!--
-->{{#if: {{{limit|}}} | <templatestyles src="Шаблон:TOC limit/styles.css" /> }}<!--
--><div class="ts-TOC_right {{#if: {{{limit|}}} | ts-TOC_limit-{{{limit|}}} }}" style="{{#if: {{{clear|}}}
| clear:{{{clear|}}};
}}{{#if: {{{width|{{{1|}}}}}}
| width:{{{width|{{{1|}}}}}};
}}{{#if: {{{max-width|}}}
| max-width: {{{max-width|}}};
}}">__TOC__</div><noinclude>
{{doc}}
</noinclude>
84311f23c6ae2f952b4496c710868089ed317e45
Шаблон:C
10
297
755
2021-11-05T11:44:04Z
ruwiki>GAndy
0
Изменил настройки защиты для «[[Шаблон:C]]»: понижение защиты согласно количеству включений (больше 2000, меньше 5000) ([Редактирование=только автоподтверждённые] (бессрочно) [Переименование=только автоподтверждённые] (бессрочно))
wikitext
text/x-wiki
{{#switch: {{{2}}}
| Р = {{{к|к}}}атегории
| Д = {{{к|к}}}атегории
| В = {{{к|к}}}атегорию
| Т = {{{к|к}}}атегорией
| П = {{{к|к}}}атегории
| ю = {{{к|к}}}атегорию
| ей | й = {{{к|к}}}атегорией
| и = {{{к|к}}}атегории
| {{{к|к}}}атегория
}} «[[:Категория:{{{1}}}|{{вложенные кавычки|{{{1}}}}}]]»<noinclude>{{doc}}</noinclude>
29dc241d0737db87ea05ae164b21b3bdc0da3f83
Шаблон:Ifempty
10
198
442
2021-11-07T14:03:01Z
ruwiki>Grain of sand
0
на модуль
wikitext
text/x-wiki
<includeonly>{{#invoke:Ifempty|main}}</includeonly><noinclude>
{{Doc}}
<!-- Add categories and interwikis to the /doc subpage, not here!
Добавляйте категории и интервики на подстраницу документации, а не сюда -->
</noinclude>
c14bef2160201468f96da309e565ff2fde725cf5
Модуль:Ifempty
828
85
144
2021-11-08T15:29:31Z
ruwiki>Ping08
0
Изменил настройки защиты для «[[Модуль:Ifempty]]»: критический шаблон или модуль: более 125000 включений ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно))
Scribunto
text/plain
local p = {}
local getArgs = require('Module:Arguments').getArgs
function p.main(frame)
local args = getArgs(frame, {removeBlanks = false})
local before = args['до']
local after = args['после']
for i, v in ipairs(args) do
if v ~= '' then
return (before or '') .. v .. (after or '')
end
end
end
return p
875e8c9f03fb4cc02d80271ad3aaab13a9bcea86
Модуль:Template call code/styles.css
828
128
298
2021-11-15T10:35:51Z
ruwiki>Jack who built the house
0
поддержка [[t:optp]] (например, на [[Модуль:Unsubst/doc]])
sanitized-css
text/css
.ts-templateCallCode-weak {
color: #72777d;
}
.ts-templateCallCode-pipe {
margin: 0 2px;
}
.ts-templateCallCode-pipe + .ts-templateCallCode-pipe,
/* Template:Optp */
.ts-templateCallCode-pipe + .ts-templateCallCode-param > .ts-templateCallCode-weak:first-child > .ts-templateCallCode-pipe:first-child {
margin-left: 0;
}
.ts-templateCallCode-param + .ts-templateCallCode-closing {
margin-left: 2px;
}
span.ts-templateCallCode > .ts-templateCallCode-templateName a {
/* Решение из https://ru.wikipedia.org/wiki/Шаблон:Фиттс */
padding: 0 0.5em !important; /* Перезаписываем стиль для .plainlinks a.external */
position: relative;
margin: -0.5em;
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
b3ed166240cf28c48a58b8d992794b753b2c6ef5
Шаблон:Lang-en
10
282
725
2022-01-02T12:52:08Z
ruwiki>Abiyoyo
0
замена редиректа прямым включением
wikitext
text/x-wiki
<nowiki />[[английский язык|англ.]] {{lang-en2|{{{1}}}}}<noinclude>
{{doc|Lang/doc}}
</noinclude>
6fcc1d4dc63f133033671bf27e48a6e701e126cb
Модуль:Wikidata/number
828
186
416
2022-01-11T01:52:22Z
ruwiki>Putnik
0
для очень старых дат timestamp меньше 0, и это ломало логику
Scribunto
text/plain
local p = {}
function p.formatVisualMagnitude ( context, options )
if ( not context ) then error( 'context not specified' ); end;
if ( not options ) then error( 'options not specified' ); end;
min = context.selectClaims( options, 'P1215[P1227:Q76596947][rank:normal,rank:preferred]' )
max = context.selectClaims( options, 'P1215[P1227:Q76596417][rank:normal,rank:preferred]' )
if ( not min or not max) then -- показываем как обычно
return context.formatPropertyDefault( context, options )
end
-- показываем Vmin-Vmax для переменной звезды
local lang = mw.language.getContentLanguage();
for _, claim1 in ipairs(min) do
for _, claim2 in ipairs(max) do
return lang:formatNum(tonumber(claim1.mainsnak.datavalue.value.amount))
.. ' − ' ..
lang:formatNum(tonumber(claim2.mainsnak.datavalue.value.amount))
end
end
end
function p.formatColorIndex( context, options )
if ( not context ) then error( 'context not specified' ); end;
if ( not options ) then error( 'options not specified' ); end;
if ( options.property ) then
-- Пролучаем все claims независимо от ранга
claims = context.selectClaims( options, options.property .. '[rank:normal,rank:preferred]' );
end
if ( claims ) then
return context.formatPropertyDefault( context, options )
end
-- Вычисляем B-V либо U-B из P1215
b = context.selectClaims( options, 'P1215[P1227:Q6746395][rank:normal,rank:preferred]' )
if ( not b ) then return end
if string.find( options.property, 'Q17773035' ) then
m1 = context.selectClaims( options, 'P1215[P1227:Q15977921][rank:normal,rank:preferred]' )
m2 = b
if ( not m1 ) then return end
else
m1 = b
m2 = context.selectClaims( options, 'P1215[P1227:Q4892529][rank:normal,rank:preferred]' )
if ( not m2 ) then return end
end
for _, claim1 in ipairs(m1) do
for _, claim2 in ipairs(m2) do
newClaim = { mainsnak = { snaktype = 'value', datavalue = { type = 'quantity',
value = { unit = '1', amount = claim1.mainsnak.datavalue.value.amount -
claim2.mainsnak.datavalue.value.amount }}}}
return context.formatStatementDefault( context, options, newClaim )
end
end
end
function p.formatPropertyWithMostRecentClaimAndIndicator( context, options )
if ( not context ) then error( 'context not specified' ); end;
if ( not options ) then error( 'options not specified' ); end;
if ( not options.entity ) then error( 'options.entity missing' ); end;
local claims;
if options.property then
-- Пролучаем все claims независимо от ранга
claims = context.selectClaims( options, options.property .. '[rank:normal,rank:preferred]' );
end
if claims == nil then
return ''
end
-- Ищем claim с максимальным значением P585 и форматируем его в out
local maxTimestamp = nil;
local mostRecentClaim;
for i, claim in ipairs(claims) do
if (claim.qualifiers and claim.qualifiers.P585) then -- обрабатываем только claims с указанным P585
local timestamp = context.parseTimeFromSnak( claim.qualifiers.P585[1] );
if timestamp ~= nil and ( maxTimestamp == nil or maxTimestamp < timestamp ) then
maxTimestamp = timestamp;
mostRecentClaim = claim
end
end
end
if (not mostRecentClaim) then -- нет ни одного claim с указанным P585
return context.formatPropertyDefault( context, options )
end
local out = context.formatStatement( options, mostRecentClaim )
if out ~= '' then
-- Ищем claim со значением P585 сразу после максимального и запоминаем его в secondMostRecentValue
local secondMostRecentTimestamp = 0;
local secondMostRecentValue = 0;
for i, claim in ipairs(claims) do
if (claim.qualifiers and claim.qualifiers.P585) then -- обрабатываем только claims с указанным P585
local timestamp = context.parseTimeFromSnak( claim.qualifiers.P585[1] )
if (timestamp ~= nil and secondMostRecentTimestamp < timestamp and maxTimestamp > timestamp) then
secondMostRecentTimestamp = timestamp
secondMostRecentValue = tonumber( claim.mainsnak.datavalue.value.amount )
end
end
end
if (secondMostRecentValue ~= 0) then -- если предыдущее значение нашлось
if (secondMostRecentValue < tonumber( mostRecentClaim.mainsnak.datavalue.value.amount )) then
out = '<span style="color: #0c0; font-size: larger;">▲</span>' .. out
else
out = '<span style="color: red; font-size: larger;">▼</span>' .. out
end
end
if options.before then
out = options.before .. out
end
if options.after then
out = out .. options.after
end
end
return out
end
function p.formatQuantityWithDateClaim( context, options, statement )
local snak = context.formatSnak( options, statement.mainsnak )
if not snak then return '' end
--Date
if ( statement.qualifiers and statement.qualifiers.P585 ) then
snak = snak .. ' (' .. context.formatSnak( options, statement.qualifiers.P585[1] ) .. ')'
end
--References
if ( options.references ) then
snak = snak .. context.formatRefs( options, statement );
end
return snak
end
function p.formatDMS( context, options, value )
if not value.amount then return value end
if options and options.unit == '-' then return value.amount end
local prefix = "+"
if tonumber( value.amount ) < 0 then
prefix = "−"
end
return p.formatAngle ( math.abs( tonumber( value.amount ) ),
string.len( value.amount ) - string.find( value.amount, '.', 1, true ) - 5,
prefix .. "%s° %02d′ %s″")
end
function p.formatRA( context, options, value )
if not value.amount then return value end
if options and options.unit == '-' then return value.amount end
return p.formatAngle (tonumber( value.amount ) / 15,
string.len( value.amount ) - string.find( value.amount, '.', 1, true ) - 4,
"%s<sup>ч</sup> %02d<sup>м</sup> %s<sup>с</sup>")
end
function p.formatAngle ( angle, sig, format )
local d, angle = math.modf( angle )
local m, angle = math.modf( angle * 60 )
local mult = 10 ^ sig;
local s = math.floor( angle * 60 * mult + 0.5 ) / mult;
local lang = mw.language.getContentLanguage();
return string.format( format, d, m, lang:formatNum( s ) )
end
return p
2f96549583b299597b7f95fbceeddad31ccee753
Шаблон:Подстраницы шаблона Карточка
10
221
490
2022-01-19T19:49:51Z
ruwiki>WindEwriX
0
fix
wikitext
text/x-wiki
{{Навигационная таблица
|имя = Подстраницы шаблона Карточка
|state = {{{state|}}}
|класс_списков = hlist hlist-items-nowrap
|заголовок = Подстраницы шаблона {{tnav|Карточка}}
|tracking = <includeonly>no</includeonly>
|группа1 = {{!}}вверху=
|список1 =
* {{tnav|карточка/название}} (заголовок без уточнения)
* {{tnav|карточка/имя}} (заголовок в обратном порядке и без уточнения)
|группа2 = {{!}}вверху2=
|список2 =
* {{tnav|карточка/оригинал названия}} (свойство [[d:P:P1705|P1705]])
* {{tnav|карточка/оригинал названия произведения}} (свойство [[d:P:P1476|P1476]])
* {{tnav|карточка/официальное название}} (свойство [[d:P:P1448|P1448]])
* {{tnav|карточка/оригинал имени}} (свойство [[d:P:P1559|P1559]])
|группа3 = Разное
|список3 =
* {{tnav|карточка/изображение}}
* {{tnav|карточка/Изображение рядом}}
* {{tnav|карточка/флаг и герб}} (свойства [[d:p:P41|P41]] и [[d:p:P94|P94]])
* {{tnav|карточка/медали}} (свойство [[d:p:P166|P166]])
* {{tnav|карточка/хронология}} (свойства [[d:p:P155|P155]] и [[d:p:P156|P156]])
* {{tnav|карточка/период}} (свойства [[d:p:P580|P580]] и [[d:p:P582|P582]])
* {{tnav|карточка/коды в каталогах}} (свойство [[d:p:P528|P528]])
* {{tnav|карточка/блок}}
* {{tnav|карточка/блок с маркерами}}
|группа4 = {{!}}внизу=
|список4 =
* {{tnav|карточка/Викиданные}}
* {{tnav|карточка/Викисклад}} (свойство [[d:P:P373|P373]])
* {{tnav|карточка/Викитека}}
* {{tnav|карточка/Викиучебник}}
* {{tnav|карточка/Викицитатник}}
|класс_внизу = hlist
|внизу =
; См. также
: [[Википедия:Шаблоны-карточки]]
: [[:Категория:Шаблоны:Для шаблонов-карточек]]
}}<noinclude>
[[Категория:Навигационные шаблоны:Для шаблонов]]
</noinclude>
f7c3cb19df3f1a23fdde48e58f259bb1f952d0ed
Шаблон:Карточка
10
129
300
2022-04-03T23:49:38Z
ruwiki>Putnik
0
пробуем красить каждую карточку на странице отдельно, без перекрытия стилей; надеюсь, комбинация имя+вверху0+вверху+вверху2 достаточно уникальна и не вызовет ошибок
wikitext
text/x-wiki
{{#if:{{{имя|}}}|{{#ifeq:{{{имя|}}}|-||{{#if:{{{цвет|}}}|{{#tag:templatestyles|
|wrapper=.infobox-{{#invoke:Hash|main|{{{имя}}} {{{вверху0|}}} {{{вверху|}}} {{{вверху2|}}}}}
|src=Шаблон:Цвет/{{{цвет|}}}.css
}}}}}}}}<table class="infobox infobox-{{#invoke:Hash|main|{{{имя}}} {{{вверху0|}}} {{{вверху|}}} {{{вверху2|}}}}} {{{класс_тела|}}}" style="{{{стиль_тела|}}}" {{#if:{{{имя|}}}|{{#ifeq:{{{имя|}}}|-||data-name="{{{имя}}}"}}}} {{#if:{{{from|}}}|{{#ifeq:{{{from|}}}|-||data-from="{{{from}}}"}}}}><!--
Вверху0
-->{{#if:{{{вверху0|}}}|<tr><td colspan="2" class="{{{класс_вверху0|}}}" style="text-align:center; {{{стиль_вверху0|}}}">{{{вверху0}}}</td></tr>}}<!--
Вверху
-->{{#if:{{{вверху|}}}|<tr><th colspan="2" scope="colgroup" class="infobox-above {{{класс_вверху|}}}" style="{{{стиль_вверху|}}}">{{{вверху}}}</th></tr>}}<!--
Вверху2
-->{{#if:{{{вверху2|}}}|<tr><td colspan="2" class="{{{класс_вверху2|}}}" style="text-align:center; {{{стиль_вверху2|}}}">{{{вверху2}}}</td></tr>}}<!--
Вверху3
-->{{#if:{{{вверху3|}}}|<tr><td colspan="2" class="{{{класс_вверху3|}}}" style="text-align:center; {{{стиль_вверху3|}}}">{{{вверху3}}}</td></tr>}}<!--
Изображение
-->{{#if:{{{изображение|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения|}}}" style="{{{стиль_изображения|}}}"> {{{изображение}}} {{#if:{{{подпись|}}}|
<div class="media-caption" style="{{{стиль_подписи|}}}">{{{подпись}}}</div>}}</td></tr>}}<!--
Изображение2
-->{{#if:{{{изображение2|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения2|}}}" style="{{{стиль_изображения2|}}}"> {{{изображение2}}} {{#if:{{{подпись2|}}}|
<div class="media-caption" style="{{{стиль_подписи2|}}}">{{{подпись2}}}</div>}}</td></tr>}}<!--
Изображение3
-->{{#if:{{{изображение3|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения3|}}}" style="{{{стиль_изображения3|}}}"> {{{изображение3}}} {{#if:{{{подпись3|}}}|
<div class="media-caption" style="{{{стиль_подписи3|}}}">{{{подпись3}}}</div>}}</td></tr>}}<!--
Строки
-->{{#invoke:Infobox|renderLines}}<!--
Внизу
-->{{Карточка/внизу|
стиль_внизу_общий={{{стиль_внизу|}}}|
класс_внизу={{{класс_внизу|}}}|
внизу={{{внизу|}}}}}<!--
Внизу N
-->{{#invoke:Transclude|npc|Карточка/внизу|
стиль_внизу_общий={{{стиль_внизу|}}}|
стиль_внизу=|
класс_внизу=|
внизу=}}
</table><includeonly><!--
статьи
-->{{#if:{{NAMESPACE}}||<!--
-->{{#if:{{{имя|}}}||[[Категория:Статьи с шаблонами-карточками без имени]]}}<!--
-->{{#ifeq:{{{имя|}}}|{{subst:PAGENAME}}|[[Категория:Статьи с шаблонами-карточками без имени]]}}<!--
-->}}<!--
шаблоны
-->{{#ifeq:{{NAMESPACENUMBER}}|10|<!--
-->{{#if:{{{имя|}}}||[[Категория:Шаблоны-карточки без имени]]}}<!--
-->{{#ifeq:{{{имя|}}}|{{subst:PAGENAME}}|[[Категория:Шаблоны-карточки без имени]]}}<!--
-->{{#if:{{{название|}}}{{{стиль_названия|}}}|[[Категория:Шаблоны с использованием параметра «название» в шаблоне «Карточка»]]}}<!--
-->{{#if:{{{подпись|}}}{{{стиль_подписи|}}}{{{подпись2|}}}{{{стиль_подписи2|}}}{{{подпись3|}}}{{{стиль_подписи3|}}}|[[Категория:Шаблоны с использованием параметра «подпись» в шаблоне «Карточка»]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_тела|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_названия|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху2|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху3|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи2|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи3|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_заголовков|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_меток|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_текста|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_внизу|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifeq:{{{имя|}}}|{{PAGENAME}}|<!--
-->[[Категория:Шаблоны-карточки по алфавиту|{{ucfirst:{{без начала|{{PAGENAME}}|Карточка }}}}]]<!--
-->{{#if:{{{стиль_тела|}}}{{{стиль_вверху|}}}{{{стиль_заголовков|}}}{{{стиль_внизу|}}}|[[Категория:Википедия:Шаблоны-карточки с явным указанием стилей]]}}<!--
-->}}<!--
-->}}<!--
любое пространство имён
-->{{#if:{{{название|}}}{{{стиль_названия|}}}|[[Категория:Википедия:Страницы с использованием параметра «название» в шаблоне «Карточка»]]}}<!--
-->{{#if:{{{подпись|}}}{{{стиль_подписи|}}}{{{подпись2|}}}{{{стиль_подписи2|}}}{{{подпись3|}}}{{{стиль_подписи3|}}}|[[Категория:Википедия:Страницы с использованием параметра «подпись» в шаблоне «Карточка»]]}}</includeonly><noinclude>{{doc}}</noinclude>
5bd0cadc0cad51dc109de7db63622ab36743d386
Шаблон:Карточка/Викисклад
10
135
312
2022-04-30T14:39:04Z
ruwiki>ShinePhantom
0
еще одна проверочная категория для зачистки
wikitext
text/x-wiki
{{wikidata|p373|{{str rep|{{str rep|{{{1|}}}|Category:|}}|category:|}}|plain=false|text=Медиафайлы на Викискладе|icon={{{icon|}}}|icon_size={{{icon_size|}}}|from={{{from|}}}}}<!--
-->{{#if: {{{nocat|}}}{{NAMESPACE}} || <!--
-->{{#if: {{{1|}}} | [[Категория:Википедия:Ссылка на Викисклад непосредственно в статье]]<!--
-->{{#if: {{wikidata|p373|plain=true}}
| {{#ifeq: {{str rep|{{str rep|{{{1|}}}|Category:|}}|category:|}} | {{wikidata|p373|plain=true}} |[[Категория:Википедия:Ссылки на Викисклад в статье и на Викиданных совпадают]]| [[Категория:Википедия:Ссылки на Викисклад в статье и на Викиданных отличаются]] }}
| [[Категория:Википедия:Ссылка на Викисклад в статье, но не на Викиданных]]
}} }}<!--
--> }}<!--
-->{{#ifeq: {{NAMESPACE}} | Шаблон | {{#if: {{{2|}}} | [[Категория:Википедия:Шаблоны для низа карточек с лишним параметром]] }} }}<!--
--><noinclude>
{{doc}}
</noinclude>
40ef9a463c772ddbf54feae9e21d4037b692253e
Шаблон:Карточка/импортёр
10
253
666
2022-05-06T07:31:20Z
176.122.109.173
0
оформление
wikitext
text/x-wiki
<includeonly>{{ {{{|safesubst:}}}require subst
| <noinclude></noinclude>{{Карточка
{{subst:!}}{{subst:#if:{{{name|}}} |имя = {{{name}}}
{{subst:!}}}}{{subst:#if:{{{bodyclass|}}} |класс_тела = {{{bodyclass}}}
{{subst:!}}}}{{subst:#if:{{{bodystyle|}}} |стиль_тела = {{{bodystyle}}}
{{subst:!}}}}{{subst:#if:{{{title|}}} |вверху = {{{title}}}
{{subst:!}}}}{{subst:#if:{{{titleclass|}}} |класс_вверху = {{{titleclass}}}
{{subst:!}}}}{{subst:#if:{{{titlestyle|}}} |стиль_вверху = {{{titlestyle}}}
{{subst:!}}}}{{subst:#if:{{{above|}}} |вверху2 = {{{above}}}
{{subst:!}}}}{{subst:#if:{{{aboveclass|}}} |класс_вверху2 = {{{aboveclass}}}
{{subst:!}}}}{{subst:#if:{{{abovestyle|}}} |стиль_вверху2 = {{{abovestyle}}}
{{subst:!}}}}{{subst:#if:{{{image|}}} |изображение = {{{image}}}
{{subst:!}}}}{{subst:#if:{{{imageclass|}}} |класс_изображения = {{{imageclass}}}
{{subst:!}}}}{{subst:#if:{{{imagestyle|}}} |стиль_изображения = {{{imagestyle}}}
{{subst:!}}}}{{subst:#if:{{{caption|}}} |подпись = {{{caption}}}
{{subst:!}}}}{{subst:#if:{{{captionstyle|}}} |стиль_подписи = {{{captionstyle}}}
{{subst:!}}}}{{subst:#if:{{{headerstyle|}}} |стиль_заголовков = {{{headerstyle}}}
{{subst:!}}}}{{subst:#if:{{{labelstyle|}}} |стиль_меток = {{{labelstyle}}}
{{subst:!}}}}{{subst:#if:{{{datastyle|}}} |стиль_текста = {{{datastyle}}}
{{subst:!}}}}{{subst:#if:{{{header1|}}} |заголовок1 = {{{header1}}}
{{subst:!}}}}{{subst:#if:{{{label1|}}} |метка1 = {{{label1}}}
{{subst:!}}}}{{subst:#if:{{{data1|}}} |текст1 = {{{data1}}}
{{subst:!}}}}{{subst:#if:{{{class1|}}} |класс1 = {{{class1}}}
{{subst:!}}}}{{subst:#if:{{{header2|}}} |заголовок2 = {{{header2}}}
{{subst:!}}}}{{subst:#if:{{{label2|}}} |метка2 = {{{label2}}}
{{subst:!}}}}{{subst:#if:{{{data2|}}} |текст2 = {{{data2}}}
{{subst:!}}}}{{subst:#if:{{{class2|}}} |класс2 = {{{class2}}}
{{subst:!}}}}{{subst:#if:{{{header3|}}} |заголовок3 = {{{header3}}}
{{subst:!}}}}{{subst:#if:{{{label3|}}} |метка3 = {{{label3}}}
{{subst:!}}}}{{subst:#if:{{{data3|}}} |текст3 = {{{data3}}}
{{subst:!}}}}{{subst:#if:{{{class3|}}} |класс3 = {{{class3}}}
{{subst:!}}}}{{subst:#if:{{{header4|}}} |заголовок4 = {{{header4}}}
{{subst:!}}}}{{subst:#if:{{{label4|}}} |метка4 = {{{label4}}}
{{subst:!}}}}{{subst:#if:{{{data4|}}} |текст4 = {{{data4}}}
{{subst:!}}}}{{subst:#if:{{{class4|}}} |класс4 = {{{class4}}}
{{subst:!}}}}{{subst:#if:{{{header5|}}} |заголовок5 = {{{header5}}}
{{subst:!}}}}{{subst:#if:{{{label5|}}} |метка5 = {{{label5}}}
{{subst:!}}}}{{subst:#if:{{{data5|}}} |текст5 = {{{data5}}}
{{subst:!}}}}{{subst:#if:{{{class5|}}} |класс5 = {{{class5}}}
{{subst:!}}}}{{subst:#if:{{{header6|}}} |заголовок6 = {{{header6}}}
{{subst:!}}}}{{subst:#if:{{{label6|}}} |метка6 = {{{label6}}}
{{subst:!}}}}{{subst:#if:{{{data6|}}} |текст6 = {{{data6}}}
{{subst:!}}}}{{subst:#if:{{{class6|}}} |класс6 = {{{class6}}}
{{subst:!}}}}{{subst:#if:{{{header7|}}} |заголовок7 = {{{header7}}}
{{subst:!}}}}{{subst:#if:{{{label7|}}} |метка7 = {{{label7}}}
{{subst:!}}}}{{subst:#if:{{{data7|}}} |текст7 = {{{data7}}}
{{subst:!}}}}{{subst:#if:{{{class7|}}} |класс7 = {{{class7}}}
{{subst:!}}}}{{subst:#if:{{{header8|}}} |заголовок8 = {{{header8}}}
{{subst:!}}}}{{subst:#if:{{{label8|}}} |метка8 = {{{label8}}}
{{subst:!}}}}{{subst:#if:{{{data8|}}} |текст8 = {{{data8}}}
{{subst:!}}}}{{subst:#if:{{{class8|}}} |класс8 = {{{class8}}}
{{subst:!}}}}{{subst:#if:{{{header9|}}} |заголовок9 = {{{header9}}}
{{subst:!}}}}{{subst:#if:{{{label9|}}} |метка9 = {{{label9}}}
{{subst:!}}}}{{subst:#if:{{{data9|}}} |текст9 = {{{data9}}}
{{subst:!}}}}{{subst:#if:{{{class9|}}} |класс9 = {{{class9}}}
{{subst:!}}}}{{subst:#if:{{{header10|}}} |заголовок10 = {{{header10}}}
{{subst:!}}}}{{subst:#if:{{{label10|}}} |метка10 = {{{label10}}}
{{subst:!}}}}{{subst:#if:{{{data10|}}} |текст10 = {{{data10}}}
{{subst:!}}}}{{subst:#if:{{{class10|}}} |класс10 = {{{class10}}}
{{subst:!}}}}{{subst:#if:{{{header11|}}} |заголовок11 = {{{header11}}}
{{subst:!}}}}{{subst:#if:{{{label11|}}} |метка11 = {{{label11}}}
{{subst:!}}}}{{subst:#if:{{{data11|}}} |текст11 = {{{data11}}}
{{subst:!}}}}{{subst:#if:{{{class11|}}} |класс11 = {{{class11}}}
{{subst:!}}}}{{subst:#if:{{{header12|}}} |заголовок12 = {{{header12}}}
{{subst:!}}}}{{subst:#if:{{{label12|}}} |метка12 = {{{label12}}}
{{subst:!}}}}{{subst:#if:{{{data12|}}} |текст12 = {{{data12}}}
{{subst:!}}}}{{subst:#if:{{{class12|}}} |класс12 = {{{class12}}}
{{subst:!}}}}{{subst:#if:{{{header13|}}} |заголовок13 = {{{header13}}}
{{subst:!}}}}{{subst:#if:{{{label13|}}} |метка13 = {{{label13}}}
{{subst:!}}}}{{subst:#if:{{{data13|}}} |текст13 = {{{data13}}}
{{subst:!}}}}{{subst:#if:{{{class13|}}} |класс13 = {{{class13}}}
{{subst:!}}}}{{subst:#if:{{{header14|}}} |заголовок14 = {{{header14}}}
{{subst:!}}}}{{subst:#if:{{{label14|}}} |метка14 = {{{label14}}}
{{subst:!}}}}{{subst:#if:{{{data14|}}} |текст14 = {{{data14}}}
{{subst:!}}}}{{subst:#if:{{{class14|}}} |класс14 = {{{class14}}}
{{subst:!}}}}{{subst:#if:{{{header15|}}} |заголовок15 = {{{header15}}}
{{subst:!}}}}{{subst:#if:{{{label15|}}} |метка15 = {{{label15}}}
{{subst:!}}}}{{subst:#if:{{{data15|}}} |текст15 = {{{data15}}}
{{subst:!}}}}{{subst:#if:{{{class15|}}} |класс15 = {{{class15}}}
{{subst:!}}}}{{subst:#if:{{{header16|}}} |заголовок16 = {{{header16}}}
{{subst:!}}}}{{subst:#if:{{{label16|}}} |метка16 = {{{label16}}}
{{subst:!}}}}{{subst:#if:{{{data16|}}} |текст16 = {{{data16}}}
{{subst:!}}}}{{subst:#if:{{{class16|}}} |класс16 = {{{class16}}}
{{subst:!}}}}{{subst:#if:{{{header17|}}} |заголовок17 = {{{header17}}}
{{subst:!}}}}{{subst:#if:{{{label17|}}} |метка17 = {{{label17}}}
{{subst:!}}}}{{subst:#if:{{{data17|}}} |текст17 = {{{data17}}}
{{subst:!}}}}{{subst:#if:{{{class17|}}} |класс17 = {{{class17}}}
{{subst:!}}}}{{subst:#if:{{{header18|}}} |заголовок18 = {{{header18}}}
{{subst:!}}}}{{subst:#if:{{{label18|}}} |метка18 = {{{label18}}}
{{subst:!}}}}{{subst:#if:{{{data18|}}} |текст18 = {{{data18}}}
{{subst:!}}}}{{subst:#if:{{{class18|}}} |класс18 = {{{class18}}}
{{subst:!}}}}{{subst:#if:{{{header19|}}} |заголовок19 = {{{header19}}}
{{subst:!}}}}{{subst:#if:{{{label19|}}} |метка19 = {{{label19}}}
{{subst:!}}}}{{subst:#if:{{{data19|}}} |текст19 = {{{data19}}}
{{subst:!}}}}{{subst:#if:{{{class19|}}} |класс19 = {{{class19}}}
{{subst:!}}}}{{subst:#if:{{{header20|}}} |заголовок20 = {{{header20}}}
{{subst:!}}}}{{subst:#if:{{{label20|}}} |метка20 = {{{label20}}}
{{subst:!}}}}{{subst:#if:{{{data20|}}} |текст20 = {{{data20}}}
{{subst:!}}}}{{subst:#if:{{{class20|}}} |класс20 = {{{class20}}}
{{subst:!}}}}{{subst:#if:{{{header21|}}} |заголовок21 = {{{header21}}}
{{subst:!}}}}{{subst:#if:{{{label21|}}} |метка21 = {{{label21}}}
{{subst:!}}}}{{subst:#if:{{{data21|}}} |текст21 = {{{data21}}}
{{subst:!}}}}{{subst:#if:{{{class21|}}} |класс21 = {{{class21}}}
{{subst:!}}}}{{subst:#if:{{{header22|}}} |заголовок22 = {{{header22}}}
{{subst:!}}}}{{subst:#if:{{{label22|}}} |метка22 = {{{label22}}}
{{subst:!}}}}{{subst:#if:{{{data22|}}} |текст22 = {{{data22}}}
{{subst:!}}}}{{subst:#if:{{{class22|}}} |класс22 = {{{class22}}}
{{subst:!}}}}{{subst:#if:{{{header23|}}} |заголовок23 = {{{header23}}}
{{subst:!}}}}{{subst:#if:{{{label23|}}} |метка23 = {{{label23}}}
{{subst:!}}}}{{subst:#if:{{{data23|}}} |текст23 = {{{data23}}}
{{subst:!}}}}{{subst:#if:{{{class23|}}} |класс23 = {{{class23}}}
{{subst:!}}}}{{subst:#if:{{{header24|}}} |заголовок24 = {{{header24}}}
{{subst:!}}}}{{subst:#if:{{{label24|}}} |метка24 = {{{label24}}}
{{subst:!}}}}{{subst:#if:{{{data24|}}} |текст24 = {{{data24}}}
{{subst:!}}}}{{subst:#if:{{{class24|}}} |класс24 = {{{class24}}}
{{subst:!}}}}{{subst:#if:{{{header25|}}} |заголовок25 = {{{header25}}}
{{subst:!}}}}{{subst:#if:{{{label25|}}} |метка25 = {{{label25}}}
{{subst:!}}}}{{subst:#if:{{{data25|}}} |текст25 = {{{data25}}}
{{subst:!}}}}{{subst:#if:{{{class25|}}} |класс25 = {{{class25}}}
{{subst:!}}}}{{subst:#if:{{{header26|}}} |заголовок26 = {{{header26}}}
{{subst:!}}}}{{subst:#if:{{{label26|}}} |метка26 = {{{label26}}}
{{subst:!}}}}{{subst:#if:{{{data26|}}} |текст26 = {{{data26}}}
{{subst:!}}}}{{subst:#if:{{{class26|}}} |класс26 = {{{class26}}}
{{subst:!}}}}{{subst:#if:{{{header27|}}} |заголовок27 = {{{header27}}}
{{subst:!}}}}{{subst:#if:{{{label27|}}} |метка27 = {{{label27}}}
{{subst:!}}}}{{subst:#if:{{{data27|}}} |текст27 = {{{data27}}}
{{subst:!}}}}{{subst:#if:{{{class27|}}} |класс27 = {{{class27}}}
{{subst:!}}}}{{subst:#if:{{{header28|}}} |заголовок28 = {{{header28}}}
{{subst:!}}}}{{subst:#if:{{{label28|}}} |метка28 = {{{label28}}}
{{subst:!}}}}{{subst:#if:{{{data28|}}} |текст28 = {{{data28}}}
{{subst:!}}}}{{subst:#if:{{{class28|}}} |класс28 = {{{class28}}}
{{subst:!}}}}{{subst:#if:{{{header29|}}} |заголовок29 = {{{header29}}}
{{subst:!}}}}{{subst:#if:{{{label29|}}} |метка29 = {{{label29}}}
{{subst:!}}}}{{subst:#if:{{{data29|}}} |текст29 = {{{data29}}}
{{subst:!}}}}{{subst:#if:{{{class29|}}} |класс29 = {{{class29}}}
{{subst:!}}}}{{subst:#if:{{{header30|}}} |заголовок30 = {{{header30}}}
{{subst:!}}}}{{subst:#if:{{{label30|}}} |метка30 = {{{label30}}}
{{subst:!}}}}{{subst:#if:{{{data30|}}} |текст30 = {{{data30}}}
{{subst:!}}}}{{subst:#if:{{{class30|}}} |класс30 = {{{class30}}}
{{subst:!}}}}{{subst:#if:{{{header31|}}} |заголовок31 = {{{header31}}}
{{subst:!}}}}{{subst:#if:{{{label31|}}} |метка31 = {{{label31}}}
{{subst:!}}}}{{subst:#if:{{{data31|}}} |текст31 = {{{data31}}}
{{subst:!}}}}{{subst:#if:{{{class31|}}} |класс31 = {{{class31}}}
{{subst:!}}}}{{subst:#if:{{{header32|}}} |заголовок32 = {{{header32}}}
{{subst:!}}}}{{subst:#if:{{{label32|}}} |метка32 = {{{label32}}}
{{subst:!}}}}{{subst:#if:{{{data32|}}} |текст32 = {{{data32}}}
{{subst:!}}}}{{subst:#if:{{{class32|}}} |класс32 = {{{class32}}}
{{subst:!}}}}{{subst:#if:{{{header33|}}} |заголовок33 = {{{header33}}}
{{subst:!}}}}{{subst:#if:{{{label33|}}} |метка33 = {{{label33}}}
{{subst:!}}}}{{subst:#if:{{{data33|}}} |текст33 = {{{data33}}}
{{subst:!}}}}{{subst:#if:{{{class33|}}} |класс33 = {{{class33}}}
{{subst:!}}}}{{subst:#if:{{{header34|}}} |заголовок34 = {{{header34}}}
{{subst:!}}}}{{subst:#if:{{{label34|}}} |метка34 = {{{label34}}}
{{subst:!}}}}{{subst:#if:{{{data34|}}} |текст34 = {{{data34}}}
{{subst:!}}}}{{subst:#if:{{{class34|}}} |класс34 = {{{class34}}}
{{subst:!}}}}{{subst:#if:{{{header35|}}} |заголовок35 = {{{header35}}}
{{subst:!}}}}{{subst:#if:{{{label35|}}} |метка35 = {{{label35}}}
{{subst:!}}}}{{subst:#if:{{{data35|}}} |текст35 = {{{data35}}}
{{subst:!}}}}{{subst:#if:{{{class35|}}} |класс35 = {{{class35}}}
{{subst:!}}}}{{subst:#if:{{{header36|}}} |заголовок36 = {{{header36}}}
{{subst:!}}}}{{subst:#if:{{{label36|}}} |метка36 = {{{label36}}}
{{subst:!}}}}{{subst:#if:{{{data36|}}} |текст36 = {{{data36}}}
{{subst:!}}}}{{subst:#if:{{{class36|}}} |класс36 = {{{class36}}}
{{subst:!}}}}{{subst:#if:{{{header37|}}} |заголовок37 = {{{header37}}}
{{subst:!}}}}{{subst:#if:{{{label37|}}} |метка37 = {{{label37}}}
{{subst:!}}}}{{subst:#if:{{{data37|}}} |текст37 = {{{data37}}}
{{subst:!}}}}{{subst:#if:{{{class37|}}} |класс37 = {{{class37}}}
{{subst:!}}}}{{subst:#if:{{{header38|}}} |заголовок38 = {{{header38}}}
{{subst:!}}}}{{subst:#if:{{{label38|}}} |метка38 = {{{label38}}}
{{subst:!}}}}{{subst:#if:{{{data38|}}} |текст38 = {{{data38}}}
{{subst:!}}}}{{subst:#if:{{{class38|}}} |класс38 = {{{class38}}}
{{subst:!}}}}{{subst:#if:{{{header39|}}} |заголовок39 = {{{header39}}}
{{subst:!}}}}{{subst:#if:{{{label39|}}} |метка39 = {{{label39}}}
{{subst:!}}}}{{subst:#if:{{{data39|}}} |текст39 = {{{data39}}}
{{subst:!}}}}{{subst:#if:{{{class39|}}} |класс39 = {{{class39}}}
{{subst:!}}}}{{subst:#if:{{{header40|}}} |заголовок40 = {{{header40}}}
{{subst:!}}}}{{subst:#if:{{{label40|}}} |метка40 = {{{label40}}}
{{subst:!}}}}{{subst:#if:{{{data40|}}} |текст40 = {{{data40}}}
{{subst:!}}}}{{subst:#if:{{{class40|}}} |класс40 = {{{class40}}}
{{subst:!}}}}{{subst:#if:{{{header41|}}} |заголовок41 = {{{header41}}}
{{subst:!}}}}{{subst:#if:{{{label41|}}} |метка41 = {{{label41}}}
{{subst:!}}}}{{subst:#if:{{{data41|}}} |текст41 = {{{data41}}}
{{subst:!}}}}{{subst:#if:{{{class41|}}} |класс41 = {{{class41}}}
{{subst:!}}}}{{subst:#if:{{{header42|}}} |заголовок42 = {{{header42}}}
{{subst:!}}}}{{subst:#if:{{{label42|}}} |метка42 = {{{label42}}}
{{subst:!}}}}{{subst:#if:{{{data42|}}} |текст42 = {{{data42}}}
{{subst:!}}}}{{subst:#if:{{{class42|}}} |класс42 = {{{class42}}}
{{subst:!}}}}{{subst:#if:{{{header43|}}} |заголовок43 = {{{header43}}}
{{subst:!}}}}{{subst:#if:{{{label43|}}} |метка43 = {{{label43}}}
{{subst:!}}}}{{subst:#if:{{{data43|}}} |текст43 = {{{data43}}}
{{subst:!}}}}{{subst:#if:{{{class43|}}} |класс43 = {{{class43}}}
{{subst:!}}}}{{subst:#if:{{{header44|}}} |заголовок44 = {{{header44}}}
{{subst:!}}}}{{subst:#if:{{{label44|}}} |метка44 = {{{label44}}}
{{subst:!}}}}{{subst:#if:{{{data44|}}} |текст44 = {{{data44}}}
{{subst:!}}}}{{subst:#if:{{{class44|}}} |класс44 = {{{class44}}}
{{subst:!}}}}{{subst:#if:{{{header45|}}} |заголовок45 = {{{header45}}}
{{subst:!}}}}{{subst:#if:{{{label45|}}} |метка45 = {{{label45}}}
{{subst:!}}}}{{subst:#if:{{{data45|}}} |текст45 = {{{data45}}}
{{subst:!}}}}{{subst:#if:{{{class45|}}} |класс45 = {{{class45}}}
{{subst:!}}}}{{subst:#if:{{{header46|}}} |заголовок46 = {{{header46}}}
{{subst:!}}}}{{subst:#if:{{{label46|}}} |метка46 = {{{label46}}}
{{subst:!}}}}{{subst:#if:{{{data46|}}} |текст46 = {{{data46}}}
{{subst:!}}}}{{subst:#if:{{{class46|}}} |класс46 = {{{class46}}}
{{subst:!}}}}{{subst:#if:{{{header47|}}} |заголовок47 = {{{header47}}}
{{subst:!}}}}{{subst:#if:{{{label47|}}} |метка47 = {{{label47}}}
{{subst:!}}}}{{subst:#if:{{{data47|}}} |текст47 = {{{data47}}}
{{subst:!}}}}{{subst:#if:{{{class47|}}} |класс47 = {{{class47}}}
{{subst:!}}}}{{subst:#if:{{{header48|}}} |заголовок48 = {{{header48}}}
{{subst:!}}}}{{subst:#if:{{{label48|}}} |метка48 = {{{label48}}}
{{subst:!}}}}{{subst:#if:{{{data48|}}} |текст48 = {{{data48}}}
{{subst:!}}}}{{subst:#if:{{{class48|}}} |класс48 = {{{class48}}}
{{subst:!}}}}{{subst:#if:{{{header49|}}} |заголовок49 = {{{header49}}}
{{subst:!}}}}{{subst:#if:{{{label49|}}} |метка49 = {{{label49}}}
{{subst:!}}}}{{subst:#if:{{{data49|}}} |текст49 = {{{data49}}}
{{subst:!}}}}{{subst:#if:{{{class49|}}} |класс49 = {{{class49}}}
{{subst:!}}}}{{subst:#if:{{{header50|}}} |заголовок50 = {{{header50}}}
{{subst:!}}}}{{subst:#if:{{{label50|}}} |метка50 = {{{label50}}}
{{subst:!}}}}{{subst:#if:{{{data50|}}} |текст50 = {{{data50}}}
{{subst:!}}}}{{subst:#if:{{{class50|}}} |класс50 = {{{class50}}}
{{subst:!}}}}{{subst:#if:{{{header51|}}} |заголовок51 = {{{header51}}}
{{subst:!}}}}{{subst:#if:{{{label51|}}} |метка51 = {{{label51}}}
{{subst:!}}}}{{subst:#if:{{{data51|}}} |текст51 = {{{data51}}}
{{subst:!}}}}{{subst:#if:{{{class51|}}} |класс51 = {{{class51}}}
{{subst:!}}}}{{subst:#if:{{{header52|}}} |заголовок52 = {{{header52}}}
{{subst:!}}}}{{subst:#if:{{{label52|}}} |метка52 = {{{label52}}}
{{subst:!}}}}{{subst:#if:{{{data52|}}} |текст52 = {{{data52}}}
{{subst:!}}}}{{subst:#if:{{{class52|}}} |класс52 = {{{class52}}}
{{subst:!}}}}{{subst:#if:{{{header53|}}} |заголовок53 = {{{header53}}}
{{subst:!}}}}{{subst:#if:{{{label53|}}} |метка53 = {{{label53}}}
{{subst:!}}}}{{subst:#if:{{{data53|}}} |текст53 = {{{data53}}}
{{subst:!}}}}{{subst:#if:{{{class53|}}} |класс53 = {{{class53}}}
{{subst:!}}}}{{subst:#if:{{{header54|}}} |заголовок54 = {{{header54}}}
{{subst:!}}}}{{subst:#if:{{{label54|}}} |метка54 = {{{label54}}}
{{subst:!}}}}{{subst:#if:{{{data54|}}} |текст54 = {{{data54}}}
{{subst:!}}}}{{subst:#if:{{{class54|}}} |класс54 = {{{class54}}}
{{subst:!}}}}{{subst:#if:{{{header55|}}} |заголовок55 = {{{header55}}}
{{subst:!}}}}{{subst:#if:{{{label55|}}} |метка55 = {{{label55}}}
{{subst:!}}}}{{subst:#if:{{{data55|}}} |текст55 = {{{data55}}}
{{subst:!}}}}{{subst:#if:{{{class55|}}} |класс55 = {{{class55}}}
{{subst:!}}}}{{subst:#if:{{{header56|}}} |заголовок56 = {{{header56}}}
{{subst:!}}}}{{subst:#if:{{{label56|}}} |метка56 = {{{label56}}}
{{subst:!}}}}{{subst:#if:{{{data56|}}} |текст56 = {{{data56}}}
{{subst:!}}}}{{subst:#if:{{{class56|}}} |класс56 = {{{class56}}}
{{subst:!}}}}{{subst:#if:{{{header57|}}} |заголовок57 = {{{header57}}}
{{subst:!}}}}{{subst:#if:{{{label57|}}} |метка57 = {{{label57}}}
{{subst:!}}}}{{subst:#if:{{{data57|}}} |текст57 = {{{data57}}}
{{subst:!}}}}{{subst:#if:{{{class57|}}} |класс57 = {{{class57}}}
{{subst:!}}}}{{subst:#if:{{{header58|}}} |заголовок58 = {{{header58}}}
{{subst:!}}}}{{subst:#if:{{{label58|}}} |метка58 = {{{label58}}}
{{subst:!}}}}{{subst:#if:{{{data58|}}} |текст58 = {{{data58}}}
{{subst:!}}}}{{subst:#if:{{{class58|}}} |класс58 = {{{class58}}}
{{subst:!}}}}{{subst:#if:{{{header59|}}} |заголовок59 = {{{header59}}}
{{subst:!}}}}{{subst:#if:{{{label59|}}} |метка59 = {{{label59}}}
{{subst:!}}}}{{subst:#if:{{{data59|}}} |текст59 = {{{data59}}}
{{subst:!}}}}{{subst:#if:{{{class59|}}} |класс59 = {{{class59}}}
{{subst:!}}}}{{subst:#if:{{{header60|}}} |заголовок60 = {{{header60}}}
{{subst:!}}}}{{subst:#if:{{{label60|}}} |метка60 = {{{label60}}}
{{subst:!}}}}{{subst:#if:{{{data60|}}} |текст60 = {{{data60}}}
{{subst:!}}}}{{subst:#if:{{{class60|}}} |класс60 = {{{class60}}}
{{subst:!}}}}{{subst:#if:{{{header61|}}} |заголовок61 = {{{header61}}}
{{subst:!}}}}{{subst:#if:{{{label61|}}} |метка61 = {{{label61}}}
{{subst:!}}}}{{subst:#if:{{{data61|}}} |текст61 = {{{data61}}}
{{subst:!}}}}{{subst:#if:{{{class61|}}} |класс61 = {{{class61}}}
{{subst:!}}}}{{subst:#if:{{{header62|}}} |заголовок62 = {{{header62}}}
{{subst:!}}}}{{subst:#if:{{{label62|}}} |метка62 = {{{label62}}}
{{subst:!}}}}{{subst:#if:{{{data62|}}} |текст62 = {{{data62}}}
{{subst:!}}}}{{subst:#if:{{{class62|}}} |класс62 = {{{class62}}}
{{subst:!}}}}{{subst:#if:{{{header63|}}} |заголовок63 = {{{header63}}}
{{subst:!}}}}{{subst:#if:{{{label63|}}} |метка63 = {{{label63}}}
{{subst:!}}}}{{subst:#if:{{{data63|}}} |текст63 = {{{data63}}}
{{subst:!}}}}{{subst:#if:{{{class63|}}} |класс63 = {{{class63}}}
{{subst:!}}}}{{subst:#if:{{{header64|}}} |заголовок64 = {{{header64}}}
{{subst:!}}}}{{subst:#if:{{{label64|}}} |метка64 = {{{label64}}}
{{subst:!}}}}{{subst:#if:{{{data64|}}} |текст64 = {{{data64}}}
{{subst:!}}}}{{subst:#if:{{{class64|}}} |класс64 = {{{class64}}}
{{subst:!}}}}{{subst:#if:{{{header65|}}} |заголовок65 = {{{header65}}}
{{subst:!}}}}{{subst:#if:{{{label65|}}} |метка65 = {{{label65}}}
{{subst:!}}}}{{subst:#if:{{{data65|}}} |текст65 = {{{data65}}}
{{subst:!}}}}{{subst:#if:{{{class65|}}} |класс65 = {{{class65}}}
{{subst:!}}}}{{subst:#if:{{{header66|}}} |заголовок66 = {{{header66}}}
{{subst:!}}}}{{subst:#if:{{{label66|}}} |метка66 = {{{label66}}}
{{subst:!}}}}{{subst:#if:{{{data66|}}} |текст66 = {{{data66}}}
{{subst:!}}}}{{subst:#if:{{{class66|}}} |класс66 = {{{class66}}}
{{subst:!}}}}{{subst:#if:{{{header67|}}} |заголовок67 = {{{header67}}}
{{subst:!}}}}{{subst:#if:{{{label67|}}} |метка67 = {{{label67}}}
{{subst:!}}}}{{subst:#if:{{{data67|}}} |текст67 = {{{data67}}}
{{subst:!}}}}{{subst:#if:{{{class67|}}} |класс67 = {{{class67}}}
{{subst:!}}}}{{subst:#if:{{{header68|}}} |заголовок68 = {{{header68}}}
{{subst:!}}}}{{subst:#if:{{{label68|}}} |метка68 = {{{label68}}}
{{subst:!}}}}{{subst:#if:{{{data68|}}} |текст68 = {{{data68}}}
{{subst:!}}}}{{subst:#if:{{{class68|}}} |класс68 = {{{class68}}}
{{subst:!}}}}{{subst:#if:{{{header69|}}} |заголовок69 = {{{header69}}}
{{subst:!}}}}{{subst:#if:{{{label69|}}} |метка69 = {{{label69}}}
{{subst:!}}}}{{subst:#if:{{{data69|}}} |текст69 = {{{data69}}}
{{subst:!}}}}{{subst:#if:{{{class69|}}} |класс69 = {{{class69}}}
{{subst:!}}}}{{subst:#if:{{{header70|}}} |заголовок70 = {{{header70}}}
{{subst:!}}}}{{subst:#if:{{{label70|}}} |метка70 = {{{label70}}}
{{subst:!}}}}{{subst:#if:{{{data70|}}} |текст70 = {{{data70}}}
{{subst:!}}}}{{subst:#if:{{{class70|}}} |класс70 = {{{class70}}}
{{subst:!}}}}{{subst:#if:{{{header71|}}} |заголовок71 = {{{header71}}}
{{subst:!}}}}{{subst:#if:{{{label71|}}} |метка71 = {{{label71}}}
{{subst:!}}}}{{subst:#if:{{{data71|}}} |текст71 = {{{data71}}}
{{subst:!}}}}{{subst:#if:{{{class71|}}} |класс71 = {{{class71}}}
{{subst:!}}}}{{subst:#if:{{{header72|}}} |заголовок72 = {{{header72}}}
{{subst:!}}}}{{subst:#if:{{{label72|}}} |метка72 = {{{label72}}}
{{subst:!}}}}{{subst:#if:{{{data72|}}} |текст72 = {{{data72}}}
{{subst:!}}}}{{subst:#if:{{{class72|}}} |класс72 = {{{class72}}}
{{subst:!}}}}{{subst:#if:{{{header73|}}} |заголовок73 = {{{header73}}}
{{subst:!}}}}{{subst:#if:{{{label73|}}} |метка73 = {{{label73}}}
{{subst:!}}}}{{subst:#if:{{{data73|}}} |текст73 = {{{data73}}}
{{subst:!}}}}{{subst:#if:{{{class73|}}} |класс73 = {{{class73}}}
{{subst:!}}}}{{subst:#if:{{{header74|}}} |заголовок74 = {{{header74}}}
{{subst:!}}}}{{subst:#if:{{{label74|}}} |метка74 = {{{label74}}}
{{subst:!}}}}{{subst:#if:{{{data74|}}} |текст74 = {{{data74}}}
{{subst:!}}}}{{subst:#if:{{{class74|}}} |класс74 = {{{class74}}}
{{subst:!}}}}{{subst:#if:{{{header75|}}} |заголовок75 = {{{header75}}}
{{subst:!}}}}{{subst:#if:{{{label75|}}} |метка75 = {{{label75}}}
{{subst:!}}}}{{subst:#if:{{{data75|}}} |текст75 = {{{data75}}}
{{subst:!}}}}{{subst:#if:{{{class75|}}} |класс75 = {{{class75}}}
{{subst:!}}}}{{subst:#if:{{{header76|}}} |заголовок76 = {{{header76}}}
{{subst:!}}}}{{subst:#if:{{{label76|}}} |метка76 = {{{label76}}}
{{subst:!}}}}{{subst:#if:{{{data76|}}} |текст76 = {{{data76}}}
{{subst:!}}}}{{subst:#if:{{{class76|}}} |класс76 = {{{class76}}}
{{subst:!}}}}{{subst:#if:{{{header77|}}} |заголовок77 = {{{header77}}}
{{subst:!}}}}{{subst:#if:{{{label77|}}} |метка77 = {{{label77}}}
{{subst:!}}}}{{subst:#if:{{{data77|}}} |текст77 = {{{data77}}}
{{subst:!}}}}{{subst:#if:{{{class77|}}} |класс77 = {{{class77}}}
{{subst:!}}}}{{subst:#if:{{{header78|}}} |заголовок78 = {{{header78}}}
{{subst:!}}}}{{subst:#if:{{{label78|}}} |метка78 = {{{label78}}}
{{subst:!}}}}{{subst:#if:{{{data78|}}} |текст78 = {{{data78}}}
{{subst:!}}}}{{subst:#if:{{{class78|}}} |класс78 = {{{class78}}}
{{subst:!}}}}{{subst:#if:{{{header79|}}} |заголовок79 = {{{header79}}}
{{subst:!}}}}{{subst:#if:{{{label79|}}} |метка79 = {{{label79}}}
{{subst:!}}}}{{subst:#if:{{{data79|}}} |текст79 = {{{data79}}}
{{subst:!}}}}{{subst:#if:{{{class79|}}} |класс79 = {{{class79}}}
{{subst:!}}}}{{subst:#if:{{{header80|}}} |заголовок80 = {{{header80}}}
{{subst:!}}}}{{subst:#if:{{{label80|}}} |метка80 = {{{label80}}}
{{subst:!}}}}{{subst:#if:{{{data80|}}} |текст80 = {{{data80}}}
{{subst:!}}}}{{subst:#if:{{{class80|}}} |класс80 = {{{class80}}}
{{subst:!}}}}{{subst:#if:{{{below|}}} |внизу = {{{below}}}
{{subst:!}}}}{{subst:#if:{{{belowstyle|}}}|стиль_внизу = {{{belowstyle}}}
}}
}}|template=Карточка/импортёр|are_params=1
}}</includeonly><noinclude>{{doc}}</noinclude>
29a99ea8472f8d4050034a77d3570f625e60bf07
Шаблон:Импортёр шаблона-карточки
10
257
674
2022-06-27T07:21:21Z
ruwiki>Leokand
0
оформление
wikitext
text/x-wiki
{{ombox
| text = Это [[Википедия:Обёртки шаблонов-карточек#Импортёры|импортёр]], преобразовывающий включение шаблона {{t|{{{3|{{PAGENAME}}}}}|lang={{#if:{{{2|}}}|{{{2|}}}|en}}}} во включение шаблона {{t|{{{1}}}}}. Для его использования выполните [[Википедия:Механизм шаблонов#Подстановка|подстановку]]: скопируйте код включения шаблона {{t|{{{3|{{PAGENAME}}}}}|lang={{#if:{{{2|}}}|{{{2|}}}|en}}}} из статьи другого раздела в статью русской Википедии, замените название шаблона:
{{(!}} width="80%" align="center"
{{!}}-
{{!}} width="45%" {{!}} <p<includeonly>r</includeonly>e>{{{{{3|{{PAGENAME}}}}}
{{pipe}} ... = ...
}}</p<includeonly>r</includeonly>e>
{{!}} →
{{!}} <p<includeonly>r</includeonly>e>{{subst:{{#if:{{{1|}}}|{{{1|}}}/импортёр|{{PAGENAME}}}}
{{pipe}} ... = ...
}}</p<includeonly>r</includeonly>e>
{{!)}}
и сохраните страницу. Пожалуйста, не забывайте после этого переводить значения параметров, если и где необходимо.
}}<includeonly>{{no-doc|nocat={{{nocat|}}}|[[Категория:Импортёры шаблонов-карточек]]}}</includeonly><noinclude>{{doc}}</noinclude>
a73640b844d55fb1ba86e8b0f62016e9e86e95a8
Шаблон:Заготовка раздела
10
201
448
2022-07-09T00:19:32Z
ruwiki>Iniquity
0
перевод на новые параметры
wikitext
text/x-wiki
{{ {{{|safesubst:}}}#invoke:Unsubst||дата=__DATE__|$format=Y-m-d|$B=
<!--{{Заготовка раздела}} begin-->{{ambox
| name = Заготовка раздела
| subst = <includeonly>{{subst:substcheck}}</includeonly>
| type = content
|image = [[Файл:Wiki letter w.svg|25px|link=|alt=]]
| issue = Этот раздел '''[[Википедия:Заготовка статьи|не завершён]]'''.
| talk = {{{talk|{{{обс|}}}}}}
| fix = Вы поможете проекту, [[Википедия:Правила и указания|исправив и дополнив]] его{{#if: {{{1|}}} | <nowiki /> следующей информацией: {{{1}}} }}.<br>{{{comment|{{{c|{{{комм|{{{ком|{{{комментарий|{{{к|{{{com|{{{comm|}}}}}}}}}}}}}}}}}}}}}}}}
| date = {{{date|{{{дата|}}}}}}
| all = Википедия:Статьи с незавершёнными разделами
| all2 = Википедия:Статьи с шаблонами недостатков по алфавиту
| nocat = {{{nocat|}}}
}}
}}<noinclude>{{doc}}</noinclude>
354fe71955c1f4efa21d425cae329d66f9b43ce6
Шаблон:Ok
10
202
450
2022-08-08T15:45:49Z
ruwiki>Sunpriat
0
wikitext
text/x-wiki
[[File:Yes check.svg|15px|link=|alt=✔]]<noinclude>
<!--alt нужен чтобы скрин-ридеры читали в атрибуте alt "✓" как "отметка" и чтобы без загрузки картинок показывалось "✓".
Без рамки "|мини" и с отключающим "|link=" подпись преобразовывается сайтом в два атрибута у img (alt и title), поэтому нужно сделать alt отдельно от title
"File" вместо "Файл" немного уменьшает размер включений шаблонов.-->
{{doc}}
</noinclude>
43161c9f08276343b6f3c9223a73c712bd7db413
Шаблон:Pipe
10
256
672
2022-08-17T10:56:05Z
ruwiki>Q-bit array
0
Изменил настройки защиты для «[[Шаблон:Pipe]]»: критический шаблон или модуль ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно))
wikitext
text/x-wiki
|<noinclude>
{{doc}}
</noinclude>
7161a16776c0ed421759a1aee1e8f465d7b8949a
Шаблон:Карточка/флаг и герб
10
170
382
2022-09-30T21:14:25Z
ruwiki>Stjn
0
+ поддержка поля from
wikitext
text/x-wiki
{{#if:{{if-wikidata|p41|{{{флаг|}}}|1|from={{{from|}}}}}{{if-wikidata|p94|{{{герб|}}}|1|from={{{from|}}}}}|<table role="presentation" style="background:inherit; border-collapse:collapse; width:100%; display:table; text-align:center;">
<tr>
{{if-wikidata|p41|{{{флаг|}}}|<td style<nowiki>=</nowiki>"vertical-align: middle">{{wikidata|p41|{{{флаг|}}}|from={{{from|}}}|border=true|size={{#if:{{{флаг ширина|}}}|{{{флаг ширина|}}}|160x160px}}|alt={{#if:{{{флаг подпись|}}} | {{{флаг подпись}}} | Флаг }} }}</td>}}
{{if-wikidata|p94|{{{герб|}}}|<td style<nowiki>=</nowiki>"vertical-align: middle">{{wikidata|p94|{{{герб|}}}|from={{{from|}}}|size={{#if:{{{герб ширина|}}}|{{{герб ширина|}}}|90x160px}}|alt={{#if:{{{герб подпись|}}} | {{{герб подпись}}} | Герб }} }}</td>}}
</tr>
{{#if:{{if-wikidata|p41|{{{флаг|}}}|1|from={{{from|}}}}}{{if-wikidata|p94|{{{герб|}}}|1|from={{{from|}}}}}|<tr>
{{if-wikidata|p41|{{{флаг|}}}|<td>{{#if:{{{флаг подпись|}}} | {{{флаг подпись}}} | Флаг }}</td>}}
{{if-wikidata|p94|{{{герб|}}}|<td>{{#if:{{{герб подпись|}}} | {{{герб подпись}}} | Герб }}</td>}}
</tr>}}</table>
}}<noinclude>{{doc}}</noinclude>
6d024d548f061491090c2a71067f26911973a9fd
Шаблон:Fmbox
10
223
494
2023-04-09T19:52:03Z
ruwiki>QBA-bot
0
Изменил настройки защиты для «[[Шаблон:Fmbox]]»: критический шаблон или модуль (добавление защиты от переименований) ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно))
wikitext
text/x-wiki
{{#invoke:Message box|fmbox}}<noinclude>
{{documentation}}
<!-- Add categories and interwikis to the /doc subpage, not here! -->
</noinclude>
dfb511d767bd2208627c0874ccf91faf6b8551cc
Шаблон:Параметры шаблона
10
224
496
2023-04-25T12:50:20Z
ruwiki>Oleg Yunakov
0
Защитил страницу [[Шаблон:Параметры шаблона]]: критический шаблон или модуль: используется на 12 991 странице ([Редактирование=администраторы и инженеры] (бессрочно) [Переименование=администраторы и инженеры] (бессрочно))
wikitext
text/x-wiki
<span title="Смотреть с помощью инструмента Templatetiger">[//dimastbkbot.toolforge.org/template_params/?template={{urlencode:{{{1|{{PAGENAME}}}}}}}&lang=ruwiki использование шаблона]</span><!-- • <span title="Смотреть с помощью инструмента Templatetiger">[//tools.wmflabs.org/templatetiger/template-parameter.php?template={{urlencode:{{{1|{{PAGENAME}}}}}}}&lang=ruwiki параметры]--> <small>[[Шаблон:Параметры шаблона|[?]]]</small><!--</span>--><noinclude>{{doc}}</noinclude>
dcd4178efbe8f098263608dce37fd93b55b863c4
Модуль:Sidebar
828
81
134
2023-04-27T11:08:04Z
ruwiki>Stjn
0
устаревший модуль, см. [[mw:Extension:Scribunto/Lua_reference_manual#strict]]
Scribunto
text/plain
--
-- Этот модуль обеспечивает работу шаблона {{Sidebar}}
--
require('strict')
local p = {}
local getArgs = require('Модуль:Arguments').getArgs
local navbar = require('Модуль:Navbar')._navbar
local function trimAndAddAutomaticNewline(s)
-- For compatibility with the original {{sidebar with collapsible lists}}
-- implementation, which passed some parameters through {{#if}} to trim
-- their whitespace. This also triggered the automatic newline behavior.
-- ([[meta:Help:Newlines and spaces#Automatic newline]])
s = mw.ustring.gsub(s, "^%s*(.-)%s*$", "%1")
if mw.ustring.find(s, '^[#*:;]') or mw.ustring.find(s, '^{|') then
return '\n' .. s
else
return s
end
end
function p.sidebar(frame, args)
if not args then
args = getArgs(frame)
end
local root = mw.html.create()
local child = args.child and mw.text.trim(args.child) == 'yes'
if not child then
root = root
:tag('table')
:addClass('vertical-navbox')
:addClass(args.wraplinks ~= 'true' and 'nowraplinks' or nil)
:addClass(args.bodyclass or args.class)
:css('float', args.float or 'right')
:css('clear', (args.float == 'none' and 'both') or args.float or 'right')
:css('width', args.width or '22.0em')
:css('margin', args.float == 'left' and '0 1.0em 1.0em 0' or '0 0 1.0em 1.0em')
:css('background', '#f9f9f9')
:css('border', '1px solid #aaa')
:css('padding', '0.2em')
:css('border-spacing', '0.4em 0')
:css('text-align', 'center')
:css('line-height', '1.4em')
:css('font-size', '88%')
:cssText(args.bodystyle or args.style)
if args.outertitle then
root
:tag('caption')
:addClass(args.outertitleclass)
:css('padding-bottom', '0.2em')
:css('font-size', '125%')
:css('line-height', '1.2em')
:css('font-weight', 'bold')
:cssText(args.outertitlestyle)
:wikitext(args.outertitle)
end
if args.topimage then
local imageCell = root:tag('tr'):tag('td')
imageCell
:addClass(args.topimageclass)
:css('padding', '0.4em 0')
:cssText(args.topimagestyle)
:wikitext(args.topimage)
if args.topcaption then
imageCell
:tag('div')
:css('padding-top', '0.2em')
:css('line-height', '1.2em')
:cssText(args.topcaptionstyle)
:wikitext(args.topcaption)
end
end
if args.pretitle then
root
:tag('tr')
:tag('td')
:addClass(args.pretitleclass)
:cssText(args.basestyle)
:css('padding-top', args.topimage and '0.2em' or '0.4em')
:css('line-height', '1.2em')
:cssText(args.pretitlestyle)
:wikitext(args.pretitle)
end
end
if args.title then
if child then
root
:wikitext(args.title)
:wikitext('</th></tr>') -- @todo replace this with unclosed again once mw.html gets it
else
root
:tag('tr')
:tag('th')
:addClass(args.titleclass)
:cssText(args.basestyle)
:css('padding', '0.2em 0.4em 0.2em')
:css('padding-top', args.pretitle and 0)
:css('font-size', '145%')
:css('line-height', '1.2em')
:cssText(args.titlestyle)
:wikitext(args.title)
end
end
if args.image then
local imageCell = root:tag('tr'):tag('td')
imageCell
:addClass(args.imageclass)
:css('padding', '0.2em 0 0.4em')
:cssText(args.imagestyle)
:wikitext(args.image)
if args.caption then
imageCell
:tag('div')
:css('padding-top', '0.2em')
:css('line-height', '1.2em')
:cssText(args.captionstyle)
:wikitext(args.caption)
end
end
if args.above then
root
:tag('tr')
:tag('td')
:addClass(args.aboveclass)
:css('padding', '0.3em 0.4em 0.3em')
:css('font-weight', 'bold')
:cssText(args.abovestyle)
:newline() -- newline required for bullet-points to work
:wikitext(args.above)
end
local rowNums = {}
for k, v in pairs(args) do
k = '' .. k
local num = k:match('^heading(%d+)$') or k:match('^content(%d+)$')
if num then table.insert(rowNums, tonumber(num)) end
end
table.sort(rowNums)
-- remove duplicates from the list (e.g. 3 will be duplicated if both heading3 and content3 are specified)
for i = #rowNums, 1, -1 do
if rowNums[i] == rowNums[i - 1] then
table.remove(rowNums, i)
end
end
for i, num in ipairs(rowNums) do
local heading = args['heading' .. num]
if heading then
root
:tag('tr')
:tag('th')
:addClass(args.headingclass)
:css('padding', '0.1em')
:cssText(args.basestyle)
:cssText(args.headingstyle)
:cssText(args['heading' .. num .. 'style'])
:newline()
:wikitext(heading)
end
local content = args['content' .. num]
if content then
root
:tag('tr')
:tag('td')
:addClass(args.contentclass)
:css('padding', '0 0.1em 0.4em')
:cssText(args.contentstyle)
:cssText(args['content' .. num .. 'style'])
:newline()
:wikitext(content)
:done()
:newline() -- Without a linebreak after the </td>, a nested list like "* {{hlist| ...}}" doesn't parse correctly.
end
end
if args.below then
root
:tag('tr')
:tag('td')
:addClass(args.belowclass)
:css('padding', '0.3em 0.4em 0.3em')
:css('font-weight', 'bold')
:cssText(args.belowstyle)
:newline()
:wikitext(args.below)
end
if not child then
local navbarArg = args.navbar or args.tnavbar
if navbarArg ~= 'none' and navbarArg ~= 'off' and (args.name or frame:getParent():getTitle():gsub('/sandbox$', '') ~= 'Шаблон:Sidebar') then
root
:tag('tr')
:tag('td')
:css('text-align', 'right')
:css('font-size', '115%')
:cssText(args.navbarstyle or args.tnavbarstyle)
:wikitext(navbar{
args.name,
mini = 1,
fontstyle = args.navbarfontstyle or args.tnavbarfontstyle
})
end
end
return tostring(root)
end
function p.collapsible(frame)
local args = getArgs(frame)
args.abovestyle = 'border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;' .. (args.abovestyle or '')
args.belowstyle = 'border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;' .. (args.belowstyle or '')
args.navbarstyle = 'padding-top: 0.6em;' .. (args.navbarstyle or args.tnavbarstyle or '')
if not args.name and frame:getParent():getTitle():gsub('/sandbox$', '') == 'Шаблон:Sidebar with collapsible lists' then
args.navbar = 'none'
end
local contentArgs = {}
for k, v in pairs(args) do
local num = string.match(k, '^list(%d+)$')
if num then
local expand = args.expanded and (args.expanded == 'all' or args.expanded == args['list' .. num .. 'name'])
local row = mw.html.create('div')
row
:addClass('NavFrame')
:addClass((not expand) and 'collapsed' or nil)
:css('border', 'none')
:css('padding', 0)
:cssText(args.listframestyle)
:cssText(args['list' .. num .. 'framestyle'])
:tag('div')
:addClass('NavHead')
:addClass(args.listtitleclass)
:css('font-size', '105%')
:css('background', 'transparent')
:css('text-align', 'left')
:cssText(args.basestyle)
:cssText(args.listtitlestyle)
:cssText(args['list' .. num .. 'titlestyle'])
:wikitext(trimAndAddAutomaticNewline(args['list' .. num .. 'title'] or 'List'))
:done()
:tag('div')
:addClass('NavContent')
:addClass(args.listclass)
:addClass(args['list' .. num .. 'class'])
:css('font-size', '105%')
:css('padding', '0.2em 0 0.4em')
:css('text-align', 'center')
:cssText(args.liststyle)
:cssText(args['list' .. num .. 'style'])
:wikitext(trimAndAddAutomaticNewline(args['list' .. num]))
contentArgs['content' .. num] = tostring(row)
end
end
for k, v in pairs(contentArgs) do
args[k] = v
end
return p.sidebar(frame, args)
end
return p
e8d033060367055f925583e3102d31899d0dce9d
Шаблон:Para
10
218
484
2023-05-02T10:07:35Z
ruwiki>Iniquity
0
занесем в проверку второй параметр
wikitext
text/x-wiki
<code style="white-space:nowrap;">|{{#if:{{{1|}}}|<span style="color:#767600;">{{{1}}}</span> = {{{2|}}}|<span style="color:#767600;">{{{2|}}}</span>}}</code><noinclude>
{{doc}}
</noinclude>
2fd0e9f403fb5a42e97b773185e89bc43323bb37
Модуль:Wikidata/url
828
285
731
2023-05-09T00:51:03Z
ruwiki>Putnik
0
оптимизация потребления памяти за счёт замены mw.wikibase.getEntity() на mw.wikibase.getBestStatements()
Scribunto
text/plain
local p = {}
local function formatLangRefs( options )
local langRefs = {}
if options.qualifiers and options.qualifiers.P407 then
for _, qualifier in ipairs( options.qualifiers.P407 ) do
if ( qualifier
and qualifier.datavalue
and qualifier.datavalue.type == 'wikibase-entityid' ) then
local qualifierId = qualifier.datavalue.value.id
local wbStatus, langRefCodeClaims = pcall( mw.wikibase.getBestStatements, qualifierId, 'P218' )
if wbStatus and langRefCodeClaims then
for _, claim in ipairs( langRefCodeClaims ) do
if ( claim.mainsnak
and claim.mainsnak.datavalue
and claim.mainsnak.datavalue.type == 'string' ) then
local langRefCode = claim.mainsnak.datavalue.value
table.insert( langRefs, options.frame:expandTemplate{ title = 'ref-' .. langRefCode } )
end
end
end
end
end
end
return table.concat( langRefs, '​' )
end
function p.formatUrlValue( context, options, value )
local moduleUrl = require( 'Module:URL' )
local langRefs = formatLangRefs( options )
if not options.length or options.length == '' then
options.length = math.max( 18, 25 - #langRefs )
end
return moduleUrl.formatUrlSingle( context, options, value ) .. langRefs
end
return p
4a9959f45666b35899729e561a73e0535c16e15e
Модуль:WikidataSelectors
828
141
324
2023-05-09T18:46:16Z
ruwiki>Putnik
0
исправление метода load()
Scribunto
text/plain
local i18n = {
["errors"] = {
["rank-not-valid"] = "Некорретное значение приоритета (rank)",
["cant-parse-condition"] = "Не удалось разобрать условие"
}
}
local validRanks = {
'best',
'preferred',
'normal',
'deprecated'
}
--[[
Internal function for error message
Input: key in errors table
Output: error message
]]
local function throwError( key )
error( i18n.errors[key] )
end
local p = {}
--[[
Load property and filter statements
Input: entityId, selector string
Output: filtered statements table
]]
function p.load( entityId, propertySelector )
local propertyId = mw.ustring.match( propertySelector, '^[Pp]%d+' )
if not propertyId then
return nil
end
propertyId = string.upper( propertyId )
local allStatements = {}
allStatements[ propertyId ] = mw.wikibase.getAllStatements( entityId, propertyId )
return p.filter( allStatements, propertySelector )
end
--[[
Parse selectors and filter statements
Input: statements table, selector string
Output: filtered statements table
]]
function p.filter( allClaims, propertySelector )
propertySelector = mw.text.trim( propertySelector )
-- Get property ID from selector
local propertyId = mw.ustring.match( propertySelector, '^[Pp]%d+' )
if not propertyId then
propertyId = ''
end
local initPos = #propertyId + 1
propertyId = string.upper( propertyId )
if ( not allClaims ) then
return nil
end
local allPropertyClaims = allClaims[propertyId]
if ( not allPropertyClaims ) then
return nil
end
-- Gathering rules
local rules = p.matchSelectors( propertySelector, initPos )
-- If there is no rank filter, than default rank is 'best'
local isRanked = false
for i, subRules in ipairs( rules ) do
for j, rule in ipairs( subRules ) do
if rule['type'] == 'rank' then
isRanked = true
break
end
end
end
if not isRanked then
table.insert( rules, 1, { { type = 'rank', value = 'best' } } )
end
-- Execute rules
allPropertyClaims = p.applyRules( allPropertyClaims, rules )
return allPropertyClaims
end
--[[
Match and gather selector rules
Input: string with selectors rules, start position
Output: rules table
]]
function p.matchSelectors( selectorsString, initPos )
local rules = {}
local rawRulePattern = '^%s*%[%s*[^%[%]]+%s*%]%s*'
local rulePattern = '^%s*%[%s*([^%[%]]+)%s*%]%s*$'
if not initPos then
initPos = 1
end
local rawRule = mw.ustring.match( selectorsString, rawRulePattern, initPos )
while rawRule do
initPos = initPos + #rawRule
rule = mw.ustring.match( rawRule, rulePattern )
rule = mw.text.trim( rule )
local subRules = mw.text.split( rule, '%s*,%s*' )
local commands = {}
local comm
for i, subRule in ipairs( subRules ) do
local isInversed = false
if mw.ustring.match( subRule, '^!' ) then
isInversed = true
subRule = mw.ustring.match( subRule, '^!%s*(.+)$' )
end
-- p123[1]
if mw.ustring.match( subRule, '^%d+$' ) then
table.insert( commands, {
type = 'position',
value = subRule,
inversed = isInversed
} )
-- p123[rank:preferred]
elseif mw.ustring.match( subRule, '^rank%s*:%s*(%a+)$' ) then
rank = mw.ustring.match( subRule, '^rank%s*:%s*(%a+)$' )
table.insert( commands, {
type = 'rank',
value = rank,
inversed = isInversed
} )
-- p123[language:xx]
elseif mw.ustring.match( subRule, '^language%s*:%s*([%a%-]+)$' ) then
value = mw.ustring.match( subRule, '^language%s*:%s*([%a%-]+)$' )
table.insert( commands, {
type = 'language',
value = value,
inversed = isInversed
} )
-- p123[language!:xx]
elseif mw.ustring.match( subRule, '^language%s*!:%s*([%a%-]+)$' ) then
value = mw.ustring.match( subRule, '^language%s*!:%s*([%a%-]+)$' )
table.insert( commands, {
type = 'language',
value = value,
inversed = not isInversed
} )
-- p123[min]
elseif mw.ustring.match( subRule, '^min$' ) then
table.insert( commands, { type = 'value_min' } )
-- p123[max]
elseif mw.ustring.match( subRule, '^max$' ) then
table.insert( commands, { type = 'value_max' } )
-- p123[min:p456]
elseif mw.ustring.match( subRule, '^min%s*:%s*[Pp]%d+$' ) then
value = mw.ustring.match( subRule, ':%s*([Pp]%d+)$' )
table.insert( commands, {
type = 'qualifier_min',
qualifier = value
} )
-- p123[max:p456]
elseif mw.ustring.match( subRule, '^max%s*:%s*[Pp]%d+$' ) then
value = mw.ustring.match( subRule, ':%s*([Pp]%d+)$' )
table.insert( commands, {
type = 'qualifier_max',
qualifier = value
} )
-- p123[unit:q789]
elseif mw.ustring.match( subRule, '^unit%s*:%s*[^%[%],:]+$' ) then
value = mw.ustring.match( subRule, ':%s*([^%[%],:]+)$' )
table.insert( commands, {
type = 'unit',
value = value,
inversed = isInversed
} )
-- p123[unit!:q789]
elseif mw.ustring.match( subRule, '^unit%s*!:%s*[^%[%],:]+$' ) then
value = mw.ustring.match( subRule, '!:%s*([^%[%],:]+)$' )
table.insert( commands, {
type = 'unit',
value = value,
inversed = not isInversed
} )
-- p123[p456]
elseif mw.ustring.match( subRule, '^[Pp]%d+$' ) then
qualifier = mw.ustring.match( subRule, '^[Pp]%d+' )
table.insert( commands, {
type = 'qualifier',
qualifier = qualifier,
value = nil,
inversed = isInversed
} )
-- p123[p456:q789]
elseif mw.ustring.match( subRule, '^[Pp]%d+%s*:%s*[^%[%],:]+$' ) then
qualifier = mw.ustring.match( subRule, '^([Pp]%d+)%s*:?' )
value = mw.ustring.match( subRule, ':%s*([^%[%],:]+)$' )
table.insert( commands, {
type = 'qualifier',
qualifier = qualifier,
value = value,
inversed = isInversed
} )
-- p123[p456!:q789]
elseif mw.ustring.match( subRule, '^[Pp]%d+%s*!:%s*[^%[%],:]+$' ) then
qualifier = mw.ustring.match( subRule, '^([Pp]%d+)%s*!:?' )
value = mw.ustring.match( subRule, '!:%s*([^%[%],:]+)$' )
table.insert( commands, {
type = 'qualifier',
qualifier = qualifier,
value = value,
inversed = not isInversed
} )
-- p123[q456]
elseif mw.ustring.match( subRule, '^[Qq]%d+$' ) then
value = mw.ustring.match( subRule, '^[Qq]%d+' )
table.insert( commands, {
type = 'value',
value = value,
inversed = isInversed
} )
else
throwError( 'cant-parse-condition' )
end
end
if #commands then
table.insert( rules, commands )
end
rawRule = mw.ustring.match( selectorsString, rawRulePattern, initPos )
end
return rules
end
--[[
Intercept statements with selector rules
Input: statements table, selector rules
Output: filtered statements table
]]
function p.applyRules( claims, rules )
for i, subRules in ipairs( rules ) do
local newClaims = {}
for j, rule in ipairs( subRules ) do
if rule['type'] == 'rank' then
table.insert( newClaims, p.filterByRank( claims, rule['value'], rule['inversed'] ) )
elseif rule['type'] == 'language' then
table.insert( newClaims, p.filterByLanguage( claims, rule['value'], rule['inversed'] ) )
elseif rule['type'] == 'unit' then
table.insert( newClaims, p.filterByUnit( claims, rule['value'], rule['inversed'] ) )
elseif rule['type'] == 'position' then
table.insert( newClaims, p.filterByPosition( claims, rule['value'], rule['inversed'] ) )
elseif rule['type'] == 'qualifier' then
table.insert( newClaims, p.filterByQualifier( claims, rule['qualifier'], rule['value'], rule['inversed'] ) )
elseif rule['type'] == 'qualifier_min' then
table.insert( newClaims, p.filterUtterByQualifier( claims, rule['qualifier'], true ) )
elseif rule['type'] == 'qualifier_max' then
table.insert( newClaims, p.filterUtterByQualifier( claims, rule['qualifier'], false ) )
elseif rule['type'] == 'value' then
table.insert( newClaims, p.filterByValue( claims, rule['value'], rule['inversed'] ) )
elseif rule['type'] == 'value_min' then
table.insert( newClaims, p.filterUtter( claims, true ) )
elseif rule['type'] == 'value_max' then
table.insert( newClaims, p.filterUtter( claims, false ) )
end
end
claims = {}
--[[
Merge all claims
TODO: It's not good
]]
for j, newSubClaims in ipairs( newClaims ) do
for k, newClaim in ipairs( newSubClaims ) do
local isNew = true
for l, oldClaim in ipairs( claims ) do
if oldClaim['id'] == newClaim['id'] then
isNew = false
break
end
end
if isNew then
table.insert( claims, newClaim )
end
end
end
end
return claims
end
--[[
Filter statements by rank
Input: claims table, rank value, inversion
Output: filtered statements table
]]
function p.filterByRank( claims, rank, inversed )
if not inversed then
inversed = false
end
if not rank then
rank = 'best'
end
-- Check if rank value is valid
local isValidRank = false
for i, validRank in ipairs( validRanks ) do
if rank == validRank then
isValidRank = true
break
end
end
if not isValidRank then
throwError( 'rank-not-valid' )
end
-- Find the best rank
if rank == 'best' then
rank = 'normal' -- default rank (don't use deprecated even if it's no more claims)
-- If we have at least one preferred rank, mark it as best
for i, statement in pairs( claims ) do
if (statement.rank == 'preferred') then
rank = 'preferred'
break
end
end
end
local resultClaims = {};
for i, statement in pairs( claims ) do
if ( statement.rank == rank ) ~= inversed then
table.insert( resultClaims, statement )
end
end
return resultClaims
end
--[[
Filter statements by language of value
Input: claims table, language, inversion
Output: filtered statements table
]]
function p.filterByLanguage( claims, language, inversed )
if not inversed then
inversed = false
end
local resultClaims = {}
local mulStatement = {}
for i, statement in ipairs( claims ) do
isMatchLanguage = false
if statement['mainsnak']
and statement['mainsnak']['datavalue']
and statement['mainsnak']['datavalue']['value']
and statement['mainsnak']['datavalue']['value']['language'] then
if statement['mainsnak']['datavalue']['value']['language'] == language then
isMatchLanguage = true
end
if statement['mainsnak']['datavalue']['value']['language'] == 'mul' then
mulStatement = statement
end
end
if isMatchLanguage ~= inversed then
table.insert( resultClaims, statement )
end
end
if next(resultClaims) == nil and next(mulStatement) ~= nil then
-- if specific language is not found, but there is Q20923490 value
table.insert( resultClaims, mulStatement )
end
return resultClaims
end
--[[
Filter statements by unit of value
Input: claims table, unit, inversion
Output: filtered statements table
]]
function p.filterByUnit( claims, unit, inversed )
if not inversed then
inversed = false
end
unit = 'http://www.wikidata.org/entity/' .. string.upper( unit )
local resultClaims = {}
for i, statement in ipairs( claims ) do
isMatchUnit = false
if statement['mainsnak']
and statement['mainsnak']['datavalue']
and statement['mainsnak']['datavalue']['value']
and statement['mainsnak']['datavalue']['value']['unit']
and statement['mainsnak']['datavalue']['value']['unit'] == unit then
isMatchUnit = true
end
if isMatchUnit ~= inversed then
table.insert( resultClaims, statement )
break
end
end
return resultClaims
end
--[[
Filter statements by position
Input: claims table, position, inversion
Output: filtered statements table
]]
function p.filterByPosition( claims, position, inversed )
if not inversed then
inversed = false
end
local resultClaims = {};
for statementPosition, statement in ipairs( claims ) do
if ( statementPosition == tonumber( position ) ) ~= inversed then
table.insert( resultClaims, statement )
break
end
end
return resultClaims
end
--[[
Filter statements by qualifier existance or it's value
Input: claims table, ID of qualifier's property, qualifier's value, inversion
Output: filtered statements table
]]
function p.filterByQualifier( claims, qualifierId, value, inversed )
if not inversed then
inversed = false
end
qualifierId = string.upper( qualifierId )
local resultClaims = {}
for i, statement in ipairs( claims ) do
if statement['qualifiers'] and statement['qualifiers'][qualifierId] then
if value == nil then
if ( #statement['qualifiers'][qualifierId] > 0 ) ~= inversed then
table.insert( resultClaims, statement )
end
else
local isQualifierFound = false
for j, qualifier in ipairs( statement['qualifiers'][qualifierId] ) do
if qualifier['datavalue'] then
local qualifierValue = qualifier['datavalue']['value']
if qualifier['datavalue']['type'] == 'wikibase-entityid' then
qualifierValue = qualifierValue.id
value = string.upper( value )
end
if qualifierValue == value then
isQualifierFound = true
break
end
end
end
if isQualifierFound ~= inversed then
table.insert( resultClaims, statement )
end
end
elseif inversed then
table.insert( resultClaims, statement )
end
end
return resultClaims
end
--[[
Filter statements by it's values
Input: claims table, value, inversed
Output: filtered statements table
]]
function p.filterByValue( claims, value, inversed )
inversed = inversed or false
local resultClaims = {}
for i, statement in ipairs( claims ) do
local statementValue
if statement['mainsnak']
and statement['mainsnak']['datavalue']
and statement['mainsnak']['datavalue']['type']
then
statementValue = statement['mainsnak']['datavalue']['value']
if statement['mainsnak']['datavalue']['type'] == 'quantity' then
statementValue = statementValue.amount
end
if statement['mainsnak']['datavalue']['type'] == 'time' then
statementValue = statementValue.time
end
if statement['mainsnak']['datavalue']['type'] == 'wikibase-entityid' then
statementValue = statementValue.id
value = string.upper( value )
end
end
if ( statementValue == value ) ~= inversed then
table.insert( resultClaims, statement )
end
end
return resultClaims
end
--[[
Find a statement with minimum or maximum value
Input: claims table, asc, inversed
Output: filtered statements table
]]
function p.filterUtter( claims, asc, inversed )
local resultValue = nil
for i, statement in ipairs( claims ) do
local statementValue
if statement['mainsnak'] and
statement['mainsnak']['datavalue'] and
statement['mainsnak']['datavalue']['type']
then
statementValue = statement['mainsnak']['datavalue']['value']
if statement['mainsnak']['datavalue']['type'] == 'quantity' then
statementValue = statementValue.amount
end
if statement['mainsnak']['datavalue']['type'] == 'time' then
statementValue = statementValue.time
end
if statement['mainsnak']['datavalue']['type'] == 'wikibase-entityid' then
statementValue = statementValue.id
end
if not resultValue or ( statementValue < resultValue ) == asc then
resultValue = statementValue
end
end
end
mw.logObject( resultValue, 'resultValue' )
return p.filterByValue( claims, resultValue, inversed )
end
--[[
Find a statement with minimum or maximum qualifier value
Input: claims table, qualifierId, asc
Output: filtered statements table
]]
function p.filterUtterByQualifier( claims, qualifierId, asc )
qualifierId = string.upper( qualifierId )
local resultValue = nil
local resultStatement = nil
for i, statement in ipairs( claims ) do
if not statement['qualifiers'] and not statement['qualifiers'][qualifierId] then
if resultStatement == nil then
resultStatement = statement
end
else
for _, qualifier in ipairs( statement['qualifiers'][qualifierId] ) do
if qualifier['datavalue'] then
local qualifierValue = qualifier['datavalue']['value']
if qualifier['datavalue']['type'] == 'quantity' then
qualifierValue = qualifierValue.amount
end
if qualifier['datavalue']['type'] == 'time' then
qualifierValue = qualifierValue.time
end
if qualifier['datavalue']['type'] == 'wikibase-entityid' then
qualifierValue = qualifierValue.id
end
if not resultValue or ( qualifierValue < resultValue ) == asc then
resultStatement = statement
resultValue = qualifierValue
end
end
end
end
end
return { resultStatement }
end
return p
0bdff3a63bf171160cdec5c966211fbbf3003880
Модуль:Wikibase
828
92
156
2023-05-09T22:41:38Z
ruwiki>Putnik
0
getEntityObject() → getEntity()
Scribunto
text/plain
-- Модуль для функционала Викиданных
local M = {};
local function tabletostr( t, fmt, s, o, c ) -- не для использования на страницах
if type( t ) == "table" then
local f = {};
for k, v in pairs( t ) do
table.insert( f, string.format( fmt or '%s = %s', k, tabletostr( v, fmt, s, o, c ) ) )
end;
table.sort( f );
return ( o or '' ) .. table.concat( f, s or '' ) .. ( c or '' )
else
return tostring( t )
end
end
function M.wbview( ref, id ) -- вспом. функция для подписи из Викиданных
local l = mw.wikibase.label( id );
return l and ( l == ref and l or ref .. '|' .. l .. ( mw.ustring.lower( l ) == mw.ustring.lower( ref ) and '' or '<sup>*</sup>' ) ) or ref
end
function M.id( frame ) -- Элемент текущей страницы в Викиданных
--Если вызван с параметром, достаёт id значения данного свойства, иначе возвращает id страницы
--Второй параметр - разделитель, если значений несколько ("; " по умолчанию),
-- либо можно указать номер параметром n. Третий параметр - формат для строкового свойства,
-- по умолчанию "%s"
local function try()
local e = mw.wikibase.getEntity();
if frame.args[ 1 ] then
local function gv( i )
local z = e.claims[ frame.args[ 1 ] ][ i ].mainsnak.datavalue;
if z.type == 'wikibase-entityid' then
return z.value.id
else
return string.format( frame.args[ 3 ] or '%s', tabletostr( z.value, "%s", '; ', '{', '}' ) )
end
end
if frame.args[ 'n' ] then
return gv( tonumber( frame.args[ 'n' ] ) )
end
local p, h = e.claims[ frame.args[ 1 ] ], {}
for n, v in pairs( p ) do
h[ n ] = gv( n )
end
return table.concat( h, frame.args[ 2 ] or "; " )
else
return e.id
end
end
local r, result = pcall( try );
if r then
return result;
else
return '<strong class="error">В Викиданных нет записей для текущей страницы</strong>';
end
end
function M.struc( frame ) -- Отладочная функция, будет перенесена в отдельный модуль
--Структуру см. [[mw:Extension:WikibaseClient/Lua#Entity table and data structure]]
local function try()
local i, e = 1, mw.wikibase.getEntity();
while frame.args[i] do
e = e[ frame.args[ i ] ] or e[ tonumber( frame.args[ i ] ) ];
i = i + 1
end
return tabletostr( e, frame.args[ 'f' ], frame.args[ 's' ] or '; ', '{', '}' )
end
local r, result = pcall( try );
if r then
return result;
else
return '<strong class="error">В Викиданных нет записей для текущей страницы</strong>';
end
end
function M.label( frame ) -- Комментарий к элементу Викиданных в 1-м параметре
local function try()
local id = frame.args[1];
if not id or id == '' then
id = mw.wikibase.getEntityIdForCurrentPage(); -- error, если нет элемента
end
return mw.wikibase.label( id );
end
local r, result = pcall( try );
if r then
return result;
else
return '<strong class="error">В Викиданных нет записей для текущей страницы</strong>';
end
end
function M.description( frame )
local function try()
local entityId = frame.args[1];
if not entityId or entityId == '' then
entityId = mw.wikibase.getEntityIdForCurrentPage(); -- error, если нет элемента
end
return mw.wikibase.description( entityId )
end
local r, result = pcall( try );
if r then
return result;
else
return '<strong class="error">В Викиданных нет записей для указанной страницы</strong>';
end
end
function M.iwiki( frame ) -- Интервики для указанного языка (только с ВД)
local function try()
if frame.args[ 1 ] then
return mw.wikibase.getEntity().sitelinks[ frame.args[ 1 ] .. 'wiki' ].title
else-- список интервик
local r = {};
for k, v in pairs( mw.wikibase.getEntity().sitelinks ) do
table.insert( r, string.format( frame.args[ 'f' ] or "* [[:%s:%s]]\n", v.language, v.title ) )
end
return table.concat( r )
end
end
local r, result = pcall( try );
if r then
return result;
else
return '<strong class="error">В Викиданных нет записей для текущей страницы</strong>';
end
end
function M.iwikiall( frame ) -- Все ссылки, привязанные к элементу на ВД, в т.ч. викигид и склад
local function try()
if frame.args[ 1 ] then
return mw.wikibase.getEntity().sitelinks[ frame.args[ 1 ] ].title
else-- список интервик
local r = {};
for k, v in pairs( mw.wikibase.getEntity().sitelinks ) do
table.insert( r, string.format( frame.args[ 'f' ] or "* [[:%s:%s]]\n", v.language, v.title ) )
end
return table.concat(r)
end
end
local r, result = pcall( try );
if r then
return result;
else
return '';
end
end
function M.page( frame ) -- страница Рувики для данного элемента
local function try()
return mw.wikibase.sitelink( frame.args[ 1 ] )
end
local r, result = pcall( try );
if r then
return result;
else
return '<strong class="error">В Викиданных нет записей для текущей страницы</strong>';
end
end
function M.wdprops( frame ) -- список всех свойств с ВД в человеко-читаемом виде
local function try()
local e, r = mw.wikibase.getEntity(), {};
for p, a in pairs( e.claims ) do
local label = mw.wikibase.label( p ) or string.format( [[d:%s]], p );
local vals = {};
for n, v in pairs( a ) do
local w = v.mainsnak.datavalue;
vals[ n ] = (
w.type == 'wikibase-entityid'
and '[[' .. M.wbview(
mw.wikibase.sitelink( w.value.id )
or 'd:' .. w.value.id,
w.value.id
) .. ']]' or M.tabletostr( w.value )
)
end
table.insert( r, string.format(
frame.args[ 'f' ] or '\n|-\n|rowspan=%i|%s\n|%s',
#vals,
label,
table.concat( vals, frame.args[ 's' ] or '\n|-\n|' )
) )
end--for
return table.concat( r )
end
local r, result = pcall( try );
if r then
return result;
else
return '<strong class="error">В Викиданных нет записей для текущей страницы</strong>';
end
end
return M
fc7c167bb9ef635b35a685123b273c486c229190
Модуль:Calendar
828
62
96
2023-05-17T17:44:45Z
ruwiki>Dima st bk
0
+ короткие варианты для английского, см. [[Обсуждение шаблона:Cite web#Формат параметра %7Carchive-date=]]
Scribunto
text/plain
local p = {}
-- Необходимые модули и переменные
local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')
local mwlang = mw.getContentLanguage()
local err = "―" -- NthDay nil result
local tCon = table.concat
-- 00) Блок многократно используемых списков
local bool_to_number={ [true]=1, [false]=0 }
local monthlang = {"января","февраля","марта","апреля","мая","июня","июля","августа","сентября","октября","ноября","декабря"}
local month_to_num = {["января"]=1,["февраля"]=2,["марта"]=3,["апреля"]=4,["мая"]=5,["июня"]=6,
["июля"]=7,["августа"]=8,["сентября"]=9,["октября"]=10,["ноября"]=11,["декабря"]=12,["-"]=""}
local monthd = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
local params = { {"г", "g"}, {"ю", "j"}}
local comment = { '<span style="border-bottom: 1px dotted; cursor: help" title="по юлианскому календарю">','</span>'}
-- duplicates:
-- AST, BST, CST, ECT, IST, MST, PST, SST,
local known_tzs = {
ACDT='+10:30', ACST='+09:30', ACT ='+08:00', ADT ='-03:00', AEDT ='+11:00',
AEST='+10:00', AFT ='+04:30', AKDT='-08:00', AKST ='-09:00', AMST ='+05:00',
AMT ='+04:00', ART ='-03:00', AST ='+03:00', AST ='+04:00', AST ='+03:00',
AST ='-04:00', AWDT='+09:00', AWST='+08:00', AZOST='-01:00', AZT ='+04:00',
BDT ='+08:00', BIOT='+06:00', BIT ='-12:00', BOT ='-04:00', BRT ='-03:00',
BST ='+06:00', BST ='+01:00', BTT ='+06:00', CAT ='+02:00', CCT ='+06:30',
CDT ='-05:00', CEDT='+02:00', CEST='+02:00', CET ='+01:00', CHAST='+12:45',
CIST='-08:00', CKT ='-10:00', CLST='-03:00', CLT ='-04:00', COST ='-04:00',
COT ='-05:00', CST ='-06:00', CST ='+08:00', CVT ='-01:00', CXT ='+07:00',
CHST='+10:00', DFT ='+01:00', EAST='-06:00', EAT ='+03:00', ECT ='-04:00',
ECT ='-05:00', EDT ='-04:00', EEDT='+03:00', EEST ='+03:00', EET ='+02:00',
EST ='-05:00', FJT ='+12:00', FKST='-03:00', FKT ='-04:00', GALT ='-06:00',
GET ='+04:00', GFT ='-03:00', GILT='+12:00', GIT ='-09:00', GMT ='+00:00',
GST ='-02:00', GYT ='-04:00', HADT='-09:00', HAST ='-10:00', HKT ='+08:00',
HMT ='+05:00', HST ='-10:00', IRKT='+08:00', IRST ='+03:30', IST ='+05:30',
IST ='+01:00', IST ='+02:00', JST ='+09:00', KRAT ='+07:00', KST ='+09:00',
LHST='+10:30', LINT='+14:00', MAGT='+11:00', MDT ='-06:00', MIT ='-09:30',
MSD ='+04:00', MSK ='+03:00', MST ='+08:00', MST ='-07:00', MST ='+06:30',
MUT ='+04:00', NDT ='-02:30', NFT ='+11:30', NPT ='+05:45', NST ='-03:30',
NT ='-03:30', OMST='+06:00', PDT ='-07:00', PETT ='+12:00', PHOT ='+13:00',
PKT ='+05:00', PST ='-08:00', PST ='+08:00', RET ='+04:00', SAMT ='+04:00',
SAST='+02:00', SBT ='+11:00', SCT ='+04:00', SLT ='+05:30', SST ='-11:00',
SST ='+08:00', TAHT='-10:00', THA ='+07:00', UTC ='+00:00', UYST ='-02:00',
UYT ='-03:00', VET ='-04:30', VLAT='+10:00', WAT ='+01:00', WEDT ='+01:00',
WEST='+01:00', WET ='+00:00', YAKT='+09:00', YEKT ='+05:00',
-- US Millitary (for RFC-822)
Z='+00:00', A='-01:00', M='-12:00', N='+01:00', Y='+12:00',
}
local category = {
["no_parameters"]=
"<!--[[Категория:Модуль:Calendar:Страницы без параметров]]-->",
["incomplete_parameters"]=
"<!--[[Категория:Модуль:Calendar:Страницы с неполными или некорректными параметрами]]-->",
["without_verification"]=
"<!--[[Категория:Модуль:Calendar:Страницы без проверки параметров]]-->",
["erroneous_parameters"]=
"<!--[[Категория:Модуль:Calendar:Страницы с ошибочными параметрами]]-->"
}
-- несколько параметров передаются вместе с кодом ошибки в таблице, один может быть передан простым значением
local e = {
["start"]="<span class=error>Ошибка: ",
["ending"]=".</span>",
["no_pattern_match"]="строка «%s» не совпадает с заданными паттернами",
["no_valid_date"]="дата «%s» не является корректной",
["wrong_jd"]="юлианская дата %s вне диапазона",
["no_data"]="нет входящих данных",
["too_many_arguments"]="ожидается менее %i аргументов",
["too_little_arguments"]="ожидается более %i аргументов",
["wrong_calculation"]="даты %s и %s не прошли проверку, %s дней разница",
["unknown_param"]="параметр %s неизвестен",
["unknown_error"]="неизвестная ошибка",
["tech_error"]="ошибка в функции %s",
["box_date"]="строка «%s» не является верной датой, пожалуйста, укажите дату в формате ГГГГ-ММ-ДД"
-- [""]="",
}
local tzs_names = {"ACDT","ACST","ACT","ADT","AEDT","AEST","AFT","AKDT","AKST",
"AMST","AMT","ART","AST","AST","AST","AST","AWDT","AWST","AZOST","AZT","BDT",
"BIOT","BIT","BOT","BRT","BST","BST","BTT","CAT","CCT","CDT","CEDT","CEST",
"CET","CHAST","CIST","CKT","CLST","CLT","COST","COT","CST","CST","CVT","CXT",
"CHST","DFT","EAST","EAT","ECT","ECT","EDT","EEDT","EEST","EET","EST","FJT",
"FKST","FKT","GALT","GET","GFT","GILT","GIT","GMT","GST","GYT","HADT","HAST",
"HKT","HMT","HST","IRKT","IRST","IST","IST","IST","JST","KRAT","KST","LHST",
"LINT","MAGT","MDT","MIT","MSD","MSK","MST","MST","MST","MUT","NDT","NFT",
"NPT","NST","NT","OMST","PDT","PETT","PHOT","PKT","PST","PST","RET","SAMT",
"SAST","SBT","SCT","SLT","SST","SST","TAHT","THA","UTC","UYST","UYT","VET",
"VLAT","WAT","WEDT","WEST","WET","YAKT","YEKT","Z","A","M","N","Y","MSK"}
local pattern = { -- для распознавания дат, переданных одним строчным параметром
{"(-?%d%d%d%d?)[-%.%s/\\](%d%d)[-%.%s/\\](%d%d)", ["order"] = {3,2,1} }, -- yyyy mm dd
{"(%d+)[-%.%s/\\](%d+)[-%.%s/\\](%d%d%d%d?)", ["order"] = {1,2,3} }, -- dd mm yyyy
{"(%d%d)[-%.%s/\\](%d%d%d%d?)", ["order"] = {2,3} }, -- mm yyyy
{"(%d%d%d%d?)[-%.%s/\\](%d%d)", ["order"] = {3,2} }, -- yyyy mm
{"(%d+)%s(%l+)%s(%d%d%d%d?)", ["order"] = {1,2,3} }, -- d mmm y
{"(%l+)%s(%d+),?%s(%d%d%d%d?)", ["order"] = {2,1,3} }, -- mmm d, y
{"(%l+)%s(%d%d%d%d?)", ["order"] = {2,3} }, -- mmm y
}
local time_units = {"year","month","day"} --не используется
--[[ local time_units = {"second", "minute", "hour",
"day_of_month", "day_of_week", "day_of_year",
"week", "month", "year", "year_of_century", "century"} ]]--
-- напоминание чтобы сделать более точные пересчёты - с часами / расчёт длительностей периодов
local mnlang = {"ru_G", "ru_N", "en", "en_S", "de", "fr"}
local month_lang = {
["ru_G"] = {"января","февраля","марта","апреля","мая","июня",
"июля","августа","сентября","октября","ноября","декабря"},
["ru_N"] = {"январь","февраль","март","апрель","май","июнь",
"июль","август","сентябрь","октябрь","ноябрь","декабрь"},
["en"] = {"january", "february", "march", "april", "may", "june",
"july", "august", "september", "october", "november", "december"},
["en_S"] = {"jan", "feb", "mar", "apr", "may", "jun",
"jul", "aug", "sep", "oct", "nov", "dec"},
["de"] = {"januar", "februar", "märz", "april", "mai", "juni",
"juli", "august", "september", "oktober", "november", "dezember"},
["fr"] = {"janvier", "février", "mars", "avril", "mai", "juin",
"juillet", "août", "septembre", "octobre", "novembre", "décembre"}
}
-- заполняется автоматически
local reverse_month_lang = {}
-- вспомогательная функция для обращения таблиц (смена ключей со значениями)
local reverse_table = function (strait_table)
local reversed_table = {}
for k,v in pairs(strait_table) do
reversed_table[v] = k
end
return reversed_table
end
-- запуск цикла по заполнению обратных таблиц, необходимых для распознавания дат
local filling_months = function (mnlang, month_lang)
for i=1, #mnlang do
reverse_month_lang[mnlang[i]] = reverse_table(month_lang[mnlang[i]])
end
end
-- 10) Блок общих функций
local function trim(str)
if not str then return nil
else return str:match'^()%s*$' and '' or str:match'^%s*(.*%S)'
end
end
local function purif(str)
if str == "" or str == nil then
return nil
elseif type(tonumber(str)) == "number" then
return math.floor(tonumber(str))
else
return nil
end
-- need .5 -- ,5 number format converter?
end
local function is(str)
if (not str) or (str == "") then return false
else return yesno(str,false)
end
end
local function init(num)
local output = {}
for i=1,num do
table.insert(output, {["year"]="", ["month"]="", ["day"]=""})
end
return unpack(output)
end
local function isyear(tbl)
if type(tbl) ~= 'table' then return false
elseif not tbl["year"] then return false
elseif type(tbl["year"]) == 'number' then return true
else return false
end
end
local function inbord(val, down, up)
return not (type(up) ~= "number" or type(down) ~= "number" or type(val) ~= "number" or up < down or val < down or val > up)
end
local function shallowcopy(orig)
local orig_type = type(orig)
local copy
if orig_type == 'table' then
copy = {}
for orig_key, orig_value in pairs(orig) do
copy[orig_key] = orig_value
end
else -- number, string, boolean, etc
copy = orig
end
return copy
end
local inlist = function ( var, list )
local n = #list
local inlist = false
for i=1,n do
if var == list[i] then inlist = true end
end
return inlist
end
-- 20) Блок общих проверочных функций, связанных с датами
local function unwarp(tbl)
if not tbl then return ""
elseif type(tbl) ~= "table" then return tbl
elseif (tbl.day or tbl.month or tbl.year) then
return (tbl.year or "?").."-"..(tbl.month or "?").."-"..(tbl.day or "?")
else return (tbl[3] or "?").."-"..(tbl[2] or "?").."-"..(tbl[1] or "?")
end
end
local function leap_year(y,jul)
if (not y) or (type(y) ~= "number")
then return false
elseif (y % 4) ~= 0
then return false
elseif not jul and (y % 100 == 0 and y % 400 ~= 0)
then return false
else return true
end
end
-- функция для вычисления последнего дня месяца для юлианского и григорианского календарей
local function month_end_day (month,year,is_julian)
local month_end_day = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} -- если не задан год, дата 29 февраля считается допустимой
if not month or type(month) ~= "number" or month < 1 or month > 12 then return nil
elseif month ~= 2 or not year then return month_end_day[month]
elseif month == 2 and (year % 4) == 0 and not ((not is_julian) and (year % 100 == 0 and year % 400 ~= 0)) then return 29
elseif month == 2 then return 28
else return nil -- в случае не целого значения входящих параметров или при иных непредусмотренных событиях
end
end
local function isdate ( chain , jul ) -- можно использовать для проверки таблиц с полями day, month, year
if not chain then return false
elseif (not type(chain) == "table")
or (not inbord(chain.year,-9999,9999))
or (not inbord(chain.month,1,12))
or (not inbord(chain.day,1,31))
or chain.day > monthd[chain.month]
-- or chain.year == 0
then return false
elseif chain.month == 2 and chain.day == 29 and not leap_year(chain.year,jul)
then return false
else return true end
-- check for other calendars needed?
end
local function ispartdate ( chain )
if not chain then return false
elseif not (type(chain) == "table") then return false
elseif (inbord(chain.year,-9999,9999)
or inbord(chain.month,1,12)
or inbord(chain.day,1,31)) then return true
else return false
end
-- partial date
-- more detailed check for 31.02.0000 needed
-- check for other calendars needed
end
-- from date1 to date2 in one year (beetwen jan-dec, dec-jan needed)
local function partdist(date1,date2)
local mont, dist = 0, 0
local d1d, d1m, d2d, d2m = (date1["day"] or ""), (date1["month"] or ""),(date2["day"] or ""), (date2["month"] or "")
if not (inbord(d1d,1,31) and inbord(d2d,1,31)) then return false end
-- нужна доп. проверка частичных дат на корректность
if (inbord(d1m,1,12) or inbord(d2m,1,12))
and (d1m == "" or d2m == "") then
mont = purif(date1["month"] or date2["month"])
d1m, d2m = mont, mont
end
-- mw.log("📏 day: " ..d1d .."->"..d2d.." month: ".. d1m.."->"..d2m )
if (inbord(d1m,1,12) and d1d <= monthd[d1m])
and (inbord(d2m,1,12) and d2d <= monthd[d2m]) then
if d2m == d1m
then dist = d2d - d1d
else dist = monthd[d1m] - d1d + d2d
end
return dist
else return math.huge
end
end
local function dmdist(d1,d2)
local p1,p2 = math.huge,math.huge
if not not partdist(d1,d2) then
p1=partdist(d1,d2)
end
if not not partdist(d2,d1) then
p1=partdist(d2,d1)
end
-- if (not p1) or (not p2) then
-- return (p1 or "") .. (p2 or "")
-- else
-- mw.log("d1, d2 = " .. undate(d1) .. ", " .. undate(d2))
return math.min(tonumber(partdist(d1,d2)) or math.huge,tonumber(partdist(d2,d1)) or math.huge)
-- end
end
-- 30) Блок функций для обработки ввода-вывода дат
local function undate(tbl)
if not tbl then return ""
else return (tbl.year or "").."-"..(tbl.month or "").."-"..(tbl.day or "")
end
end
-- функция для нормализации значений дат и перевода месяцев в числа
local function numerize(str)
if type(str) == "number" then
return math.floor(str)
elseif str == "" or str == nil or type(str) ~= "string" then
return nil
elseif type(tonumber(str)) == "number" then
return math.floor(tonumber(str))
else
for i=1, #mnlang do
if inlist(mw.ustring.lower(str),month_lang[mnlang[i]]) then
return reverse_month_lang[mnlang[i]][mw.ustring.lower(str)]
end
end
end
end
-- функция распознавания даты, переданной одной строкой
local function parse_date(date_string)
if type(date_string) ~= "string" or date_string == "" then return nil end
local out_date_str = {"","",""}
local error_data = {}
for i=1, #pattern do
local result_1, result_2, result_3 = mw.ustring.match(mw.ustring.lower(date_string),pattern[i][1])
if (result_1 or "") > "" then
out_date_str[pattern[i].order[1]] = result_1
out_date_str[pattern[i].order[2]] = result_2
if (pattern[i].order[3]) then out_date_str[pattern[i].order[3]] = result_3 end
-- mw.log("Паттерн " .. i .. ", строка: " .. date_string)
break
end
end
local date = {
["day"] =numerize(out_date_str[1]),
["month"]=numerize(out_date_str[2]),
["year"] =numerize(out_date_str[3])}
return date --, error_data
end
----[[ УСТАРЕЛО ]]----
local numstr2date = function(numstr)
local format = "Y-m-d"
local iso_date = mwlang:formatDate(format,numstr)
local y,m,d = string.match(iso_date, "(%d+)-(%d+)-(%d+)")
local dateout = {["year"]=purif(y), ["month"]=purif(m), ["day"]=purif(d)}
return dateout
end
--local numstr2date = function(numstr)
-- local nums = {}
-- local dateout = {}
-- for num in string.gmatch(numstr,"(%d+)") do
-- table.insert(nums,purif(num))
-- end
-- if #nums ~= 3 then error("В поле даты вместо трёх чисел с разделителями указано " .. #nums)
-- elseif not inbord(nums[2],1,12) then error("Месяц с номером " .. nums[2] .. " не найден")
-- elseif not inbord(nums[3],1,31) then
-- dateout = {["year"]=nums[3], ["month"]=nums[2], ["day"]=nums[1]}
-- elseif not inbord(nums[1],1,31) then
-- dateout = {["year"]=nums[1], ["month"]=nums[2], ["day"]=nums[3]}
-- elseif inbord(nums[1],1,31) then
-- dateout = {["year"]=nums[3], ["month"]=nums[2], ["day"]=nums[1]}
-- else
-- local mwlang = mw.getContentLanguage()
-- implement mwlang:formatDate(format,datein,true) here
-- return error("Не распознано " .. numstr .. " как дата")
-- end
-- return dateout
--end
local function year2lang(numyear,yearmark,wiki)
if not numyear then return "" end
if not yearmark then yearmark = "" end
local output = ""
local bcmark = " до н. э."
if numyear > 0 then bcmark = ""
else numyear = 1 - numyear end
if wiki then
-- output = tCon({'[[', numyear,' год',bcmark,'|', numyear,']]', " ", yearmark, " ", bcmark})
output = tCon({'[[', numyear,' год',bcmark,'|', trim(numyear .. " " .. yearmark .. " " .. bcmark), ']]'})
else
output = tCon({numyear, " ", yearmark, bcmark})
end
return trim(output)
end
local function day2lang(datein,wikidate,wiki,inner_brt)
-- if not isdate(wikidate) then wiki = false end
if not ispartdate(datein) then return "" end
local dm_separ, output = "", nil
if (not (not datein.day)) and (not (not datein.month)) then dm_separ = " " end
if (not datein.month) then datein.month = "" end
if (not datein.day) then datein.day = "" end
local monlan = monthlang[datein.month] or ""
if wiki and not inner_brt then
output = tCon({"[[", wikidate.day, " ", monthlang[wikidate.month] or "",
"|", (datein.day or ""), dm_separ, monlan, "]]"})
elseif wiki then
output = tCon({"[[", wikidate.day, " ", monthlang[wikidate.month] or "",
"|", (datein.day or ""), dm_separ, monlan})
else
output = tCon({datein.day, dm_separ, monlan})
end
return trim(output)
end
local function triple_txt2date(d,m,y)
-- добавить (args[1]:match("(%a+)") or "-") для нестандартной записи
-- mw.ustring.match((m or ""),"(%a+)")
local msg = ""
local year = purif((y or "-"):match("(%d+)"))
local month = purif(month_to_num[string.lower(mw.ustring.match((m or ""),"(%a+)"))])
local day = purif((d or "-"):match("(%d+)"))
if not month then
msg = category.incomplete_parameters
month = purif(month_to_num[string.lower(mw.ustring.match((d or ""),"(%a+)") or "-")])
end
if (not day) and ((purif(string.match(m or "","(%d+)") or "") or 32) <= (monthd[month] or 31)) then
msg = category.incomplete_parameters
day = purif(m:match("(%d+)") or "")
end
if not year then
msg = category.incomplete_parameters
year = purif(string.match(m or "","(%d+)") or "")
end
local dateout = {["year"]=year, ["month"]=month, ["day"]=day, ["msg"]=msg}
return dateout
end
local function glue(d1,m1,y1,d2,m2,y2)
if (not d1) and (not m1) and (not y1) and (not d2) and (not m2) and (not y2) then
return category.incomplete_parameters end
local gd,gm,gy,jd,jm,jy =
(d1 or ""),
(m1 or ""),
(y1 or ""),
(d2 or ""),
(m2 or ""),
(y2 or "")
--mw.log(tCon({gd,gm,gy,jd,jm,jy}))
local gm_sep = {" [["," год|","]]"}
if (not gy) or (gy == "") then gm_sep = {"","",""} end
return tCon({comment[1],trim(trim(jd .. " " .. jm) .. " " .. jy ),
comment[2]," ([[",trim(gd .. " " .. gm),"]]",gm_sep[1],(gy:match("(%d+)") or ""),
gm_sep[2],gy,gm_sep[3],")",category.incomplete_parameters})
end
-- добавить отображение без года
local function double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark)
local msg = ""
msg = (jdate.msg or "") .. (gdate.msg or "")
local cd = {}
local jd = shallowcopy(jdate)
local gd = shallowcopy(gdate)
local left = "("
local right = ")"
if sq_brts then
left = "["
right = "]"
end
if (not isdate(jdate,true)) then return error((jdate.day or "") .. "." .. (jdate.month or "") .."." .. (jdate.year or "") .. " неподходящая дата")
elseif (not isdate(gdate)) then return error((gdate.day or "") .. "." .. (gdate.month or "") .."." .. (gdate.year or "") .. " неподходящая дата") end
if jd.year == gd.year then
cd.year = gd.year
gd.year, jd.year = nil, nil
end
if jd.month == gd.month then
cd.month = gd.month
gd.month, jd.month = nil, nil
end
if (not not cd.month) and wm then
return tCon({comment[1] .. trim(day2lang(jd,jdate,false) .. " " .. year2lang(jd.year,yearmark,false)) .. comment[2],
trim(left .. day2lang(gd,gdate,wd,wm) .. " " .. year2lang(gd.year,yearmark,wy)) .. right,
day2lang(cd,gdate,false) .. "]]", trim(year2lang(cd.year,yearmark,wy)..msg)}, " ")
end
return tCon({comment[1] .. trim(day2lang(jd,jdate,false) .. " " .. year2lang(jd.year,yearmark,false)) .. comment[2],
trim(left .. day2lang(gd,gdate,wd) .. " " .. year2lang(gd.year,yearmark,wy)) .. right,
trim(day2lang(cd,gdate,false)), trim(year2lang(cd.year,yearmark,wy)..msg)}, " ")
end
-- 40) Блок функций для перевода дат с использованием [[Юлианская дата]]
local function gri2jd( datein )
if not isdate(datein) then return error((datein.day or "") .. "." .. (datein.month or "") .."." .. (datein.year or "") .. " неподходящая дата") end
local year = datein.year
local month = datein.month
local day = datein.day
-- jd calculation
local a = math.floor((14 - month)/12)
local y = year + 4800 - a
local m = month + 12*a - 3
local offset = math.floor(y/4) - math.floor(y/100) + math.floor(y/400) - 32045
local jd = day + math.floor((153*m + 2)/5) + 365*y + offset
-- jd validation
local low, high = -1931076.5, 5373557.49999
if not (low <= jd and jd <= high) then
return error((datein.day or "") .. "." .. (datein.month or "") .. "." .. (datein.year or "") .. " выходит за пределы разрешённого диапазона")
end
return jd
end
local function jd2jul( jd )
if type(jd) ~= "number" then return error("Промежуточная переменная " .. (jd or "") .. " не является числом") end
-- calendar date calculation
local c = jd + 32082
local d = math.floor((4*c + 3)/1461)
local e = c - math.floor(1461*d/4)
local m = math.floor((5*e + 2)/153)
local year_out = d - 4800 + math.floor(m/10)
local month_out = m + 3 - 12*math.floor(m/10)
local day_out = e - math.floor((153*m + 2)/5) + 1
-- output
local dateout = {["year"]=year_out, ["month"]=month_out, ["day"]=day_out}
return dateout
end
local function jul2jd( datein )
if not isdate(datein,true) then return error((datein.day or "") .. "." .. (datein.month or "") ..".".. (datein.year or "") .. " неподходящая дата") end
local year = datein.year
local month = datein.month
local day = datein.day
-- jd calculation
local a = math.floor((14 - month)/12)
local y = year + 4800 - a
local m = month + 12*a - 3
local offset = math.floor(y/4) - 32083
local jd = day + math.floor((153*m + 2)/5) + 365*y + offset
-- jd validation
local low, high = -1930999.5, 5373484.49999
if not (low <= jd and jd <= high) then
return error((datein.day or "") .. "." .. (datein.month or "") .."." .. (datein.year or "") .. " выходит за пределы разрешённого диапазона")
end
return jd
end
local function jd2gri( jd )
if type(jd) ~= "number" then return error("Промежуточная переменная " .. (jd or "") .. " не является числом") end
-- calendar date calculation
local a = jd + 32044
local b = math.floor((4*a + 3) / 146097)
local c = a - math.floor(146097*b/4)
local d = math.floor((4*c+3)/1461)
local e = c - math.floor(1461*d/4)
local m = math.floor((5*e+2)/153)
local day_out = e - math.floor((153*m+2)/5)+1
local month_out = m + 3 - 12*math.floor(m/10)
local year_out = 100*b + d - 4800 + math.floor(m/10)
-- output
local dateout = {["year"]=year_out, ["month"]=month_out, ["day"]=day_out}
return dateout
end
local function astroyear(num, bc)
if not num then return error()
elseif type(num) ~= "number" then return error()
end
if num < 1 then return num end
if not bc then return num
else return 1 - num
end
end
local function recalc(datein,calend)
if inlist(calend,params[1]) then
return jd2jul(gri2jd(datein)), datein
elseif inlist(calend,params[2]) then
return datein, jd2gri(jul2jd(datein))
else error("Параметр " .. (calend or "") .. " не опознан, разрешённые: " .. tCon(params[1]," ") .. " и " .. tCon(params[2]," "))
end
end
-- 50) Функции для обработки UTC
local function utc(str,margin)
local d = 1
local dchar = "+"
local beginning = "[[UTC"
local ending = "]]"
local cat = ""
local nums = {}
local hmarg, timedec = 0, 0
local mmarg = "00"
local output = ""
-- checking type of input
if not margin then margin = 0
elseif type(tonumber(margin)) ~= 'number' then
output = "Can't shift by " .. margin
error(output)
end
if type(str) ~= 'string' then
error("Нет входящей строки")
elseif str:byte(1) == 43 then
elseif inbord(str:byte(1),48,57) then cat = "[[Категория:Википедия:Ошибка в часовом поясе НП]]"
elseif str:byte(1) == 45 or string.sub(str,1,3) == "−" or string.sub(str,1,1)=="-" then d = -1
else
error(string.char(str:byte(1)) .. " недопустимый первый символ")
end
-- parsing input
for num in string.gmatch(str,"(%d+)") do
table.insert(nums,purif(num))
end
if #nums > 2 then error("Ожидается всего 2 числа, а не " .. #nums)
elseif #nums == 0 then error("Необходимо что-то ввести")
elseif #nums == 1 then
if inbord(nums[1],0,14) then timedec = d*nums[1] + margin
else error("Только часы от -14 до 14") end
elseif #nums == 2 then
if not inbord(nums[1],0,14) then error("Только часы от -14 до 14")
elseif not inbord(nums[2],0,59) then error("Минуты только от 0 до 59")
else
timedec = d*(nums[1] + nums[2]/60) + margin
end
end
if tonumber(timedec) == purif(timedec) then hmarg = timedec
else
local h, m = math.modf(math.abs(timedec))
hmarg = h
mmarg = math.floor(m*60)
end
if timedec == 0 then
dchar = "±"
elseif timedec > 0 then
elseif timedec < 0 then
dchar = "−"
end
-- output
output = beginning .. dchar .. math.abs(hmarg) .. ":" .. string.format("%02d",mmarg) .. ending .. cat
return output
end
-- 60) Блок функций ввода-вывода
function p.NthDay( frame )
local args = getArgs(frame, { frameOnly = true })
local num, wday, mont, yea, format =
purif(args[1]), purif(args[2]), purif(args[3]), purif(args[4]), args[5]
if not format then format = "%d.%m.%y" end
if not inbord(num,-5,5) then
return error("The number must be between -5 and 5")
elseif num == 0 then
return error("The number must not be zero") end
if not inbord(wday,0,6) then
return error("The day of the week must be between 0 and 6") end
if not inbord(mont,1,12) then
return error("The month must be between 1 and 12") end
if not inbord(yea,0,9999) then
return error("Wrong year number") end
if inbord(num,1,5) then
local m_start = os.time{year=yea, month=mont, day=1, hour=0}
local m_wds = tonumber(os.date("%w", m_start))
local start_shift = (
(num - bool_to_number[wday >= m_wds]) * 7
- (m_wds - wday)
) * 24 * 60 * 60
local tim = m_start + start_shift
if tonumber(os.date("%m", tim)) == mont then
return (os.date(format, tim))
else
return (err)
end
elseif inbord(num,-5,-1) then
local m_end = os.time{year = yea, month = mont + 1, day = 1, hour = 0} - 24 * 60 * 60
local m_wde = tonumber(os.date("%w", m_end))
local end_shift = ((math.abs(num + 1) + bool_to_number[wday > m_wde]) * 7
+ (m_wde - wday)) * 24 * 60 * 60
local tim = m_end - end_shift
if tonumber(os.date("%m", tim)) == mont then
return (os.date(format, tim))
else
return (err)
end
end
end
-- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"12 декабря 2020"}})
-- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"1.2.1602"}})
-- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"12.12.2021"}})
-- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"2021.12.12"}})
function p.ToIso( frame )
local args = getArgs(frame, { frameOnly = true })
local datein = args[1]
-- инициализация, заполнение обратных таблиц, копирование параметров
filling_months(mnlang, month_lang)
-- парсинг входящей даты по шаблону
local date = parse_date(datein)
if not (type(date.year) == 'number') then
return ("Wrong year: " .. unwarp(date))
end
if not (1 <= date.month and date.month <= 12) then
return ("Wrong month: " .. unwarp(date))
end
if not date.day or not (1 <= date.day and date.day <= month_end_day(date.month,date.year)) then
return ("Wrong day: " .. unwarp(date))
end
local timedate = os.time{year=date.year, month=date.month, day=date.day}
local date = os.date("%Y-%m-%d", timedate)
return date
end
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12 декабря 2020"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"1.2.1602"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"декабрь 2020"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12-2020"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12.12.2021"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"2021.12.12"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"2021.11"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"11.2021"}})
function p.BoxDate( frame )
local args = getArgs(frame, { frameOnly = true })
local txtDateIn, strFormat = args[1], args[2]
local txtDateOut, date, status = p.bxDate(txtDateIn, strFormat, params)
if status.brk then
return error(status.errorText)
else
return txtDateOut
end
end
function p.bxDate( txtDateIn , strFormat, params ) -- к отладке
local txtDateOut, date, status = "", {}, {brk = false, errorCat = "", errorText = ""}
strFormat = strFormat or "j xg Y"
-- заглушка - таблица параметров на будущее
params = params or {}
if not txtDateIn then
status.errorText = e.no_data
status.errorCat = category.no_parameters
status.brk = true
else
-- заполнение служебных таблиц
filling_months(mnlang, month_lang)
end
if not status.brk then
-- парсинг входящей даты по шаблону
date = parse_date(txtDateIn)
-- заменить сообщения об ошибках на списочные
if not (date.year and type(date.year) == 'number') then
status.errorText = string.format(e.box_date,txtDateIn)
status.errorCat = category.incomplete_parameters
status.brk = true
end
if not inbord(date.month,1,12) then
status.errorText = string.format(e.box_date,txtDateIn)
status.errorCat = category.incomplete_parameters
status.brk = true
end
if not date.day and string.find(strFormat,"[dDjlNwzW]") then
strFormat = trim(string.gsub(string.gsub(strFormat,"xg","F"),"[dDjlNwzW]",""))
elseif not date.day then
elseif not inbord(date.day,1,month_end_day(date.month,date.year)) then
status.errorText = string.format(e.box_date,txtDateIn)
status.errorCat = category.incomplete_parameters
status.brk = true
end
end
if not status.brk then
txtDateOut = mwlang:formatDate(strFormat,tCon({date.year,date.month,date.day},"-"),true)
end
return txtDateOut, date, status
end
function p.ToDate( frame ) -- возможно неиспользуемая
local args = getArgs(frame, { frameOnly = true })
local mwlang = mw.getContentLanguage()
local datein = args[1]
local format = "j xg Y"
if not string.match(datein, "%p") then return datein
elseif not args[2] then
else format = args[2]
end
return mwlang:formatDate(format,datein,true)
end
-- =p.unitime(mw.getCurrentFrame():newChild{title="smth",args={"−1:30","1"}})
function p.unitime( frame )
local args = getArgs(frame, { frameOnly = true })
local DST = 0
if not args[2] then
else DST = 1 end
local utcin = ""
local input = args[1]
if not input then return "" end
if inlist(input:upper(),tzs_names) then
utcin = known_tzs[input:upper()]
elseif (string.sub(input:upper(),1,3) == 'UTC') and (string.len(input) < 10) then
utcin = string.sub(input,4)
else
if string.sub(input,1,1) == '['
or string.sub(input,1,1) == '{'
or string.sub(input,1,1):upper() == 'U'
or string.sub(input,1,1):upper() == 'M' then
return input
-- elseif not string.find(string.upper(string.sub(input,1,1)),"[\65-\90]") or
-- not string.find(string.upper(string.sub(input,1,1)),"[\192-\223]") then
-- return input
else utcin = input end
end
-- elseif string.sub(input,1,3) ~= "−" then utcin = input
-- or not (not input:find("[А-я]")) при наличии в строке юникода не работает
local output = ""
if DST == 0 then output = utc(utcin)
else output = utc(utcin) .. ", [[летнее время|летом]] " .. utc(utcin,DST)
end
return output
end
-- УСТАРЕЛО
-- =p.OldDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020","ю",["bc"]="1",["wd"]="1",["wy"]="1",["sq_brts"]="1",["yearmark"]="г."}})
function p.OldDate( frame )
local args = getArgs(frame, { frameOnly = true })
if not args[1] then return err end
local gdate, jdate = {}, {}
local strin = args[1]
local cal = args[2]:lower() or "г"
local bc = is(args["bc"])
local wd = is(args["wd"])
local wm = is(args["wm"])
local wy = is(args["wy"])
if not wd then wm = false end
local sq_brts = is(args["sq_brts"])
local yearmark = "года"
if yesno(args["yearmark"]) then
elseif yesno(args["yearmark"]) == false then yearmark = ""
else yearmark = trim(args["yearmark"]) or "года" end
-- local infocard = is(args["infocard"])
-- local catName = args["catName"] or false
local datein = numstr2date(strin)
datein.year = astroyear(datein.year, bc)
jdate, gdate = recalc(datein,cal)
return double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark)
end
-- =p.NewDate(mw.getCurrentFrame():newChild{title="Salt",args={"2020-02-20"}})
-- =p.NewDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020","ю",["bc"]="1",["wd"]="1",["wy"]="1",["sq_brts"]="1",["yearmark"]="г."}})
-- =p.NewDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020",["bc"]="0",["wd"]="1",["wy"]="1",["sq_brts"]="0",["yearmark"]=""}})
function p.NewDate( frame )
local args = getArgs(frame, { frameOnly = true })
if not args[1] then return err end
local strin = args[1]
local year, month, day
if not not strin:match( "(-?%d%d%d%d%d)-(%d%d)-(%d%d)" ) then
year, month, day = strin:match( "(-?%d%d%d%d%d)-(%d%d)-(%d%d)" )
elseif not not strin:match( "(-?%d+)-(%d+)-(%d+)" ) then
year, month, day = strin:match( "(-?%d+)-(%d+)-(%d+)" )
elseif not not strin:match( "(%d%d)%.(%d%d)%.(-?%d%d%d%d%d)" ) then
day, month, year = strin:match( "(%d%d)%.(%d%d)%.(-?%d%d%d%d%d)" )
elseif not not strin:match( "(%d+)%.(%d+)%.(-?%d+)" ) then
day, month, year = strin:match( "(%d+)%.(%d+)%.(-?%d+)" )
end
if not year then return error(args[1] .. " не подходит под форматы yyyy-mm-dd или dd.mm.yyyy")
end
local cal = "г"
if (not args[2]) or (args[2] == "") then cal = "г"
else cal = args[2]:lower() end
local bc,wd,wm,wy,sq_brts =
is(args["bc"]),
is(args["wd"]),
is(args["wd"]) and is(args["wm"]),
is(args["wy"]),
is(args["sq_brts"])
year = astroyear(purif(year),bc)
local datein = {["year"]=purif(year), ["month"]=purif(month), ["day"]=purif(day)}
local jdate, gdate = recalc(datein,cal)
local yearmark = "года"
local ym = args["yearmark"] or ""
if yesno(ym) then
elseif yesno(ym) == false then yearmark = ""
else
if not not ym:match("(%d+)") then
error("Цифры в обозначении года: " .. ym)
else yearmark = trim(ym) or "года" end
end
return double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark)
end
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"3","июня",nil,"21","мая"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28 августа","","1916 года","15"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"3","июня","1900","21","мая"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"6","июня","1889 год","25","мая"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28","ноября","1917","15"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28 августа","nil","1916 года","15"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"4","января","1915","22","декабря","1914 года"}})
-- {{OldStyleDate|день (НС)|месяц (НС)|год (НС)|день (СС)|месяц (СС)|год (СС)}}
function p.Test( frame )
local args = getArgs(frame, { frameOnly = true })
-- необходима проверка и замена nil на " "
--[[mw.log((args[1] or "") .. " " ..
(args[2] or "") .. " " ..
(args[3] or "") .. " " ..
(args[4] or "") .. " " ..
(args[5] or "") .. " " ..
(args[6] or "")) ]]--
local ingdate = triple_txt2date(args[1],args[2],args[3])
local injdate = triple_txt2date(args[4],args[5],args[6])
local j1date, g1date, j2date, g2date = init(4)
mw.log("ingdate-".. (undate(ingdate) or ""))
mw.log("injdate-".. (undate(injdate) or ""))
local bc,wd,wm,wy,sq_brts,ny =
is(args["bc"]),
is(args["wd"]),
is(args["wd"]) and is(args["wm"]),
is(args["wy"]),
is(args["sq_brts"]),
is(args["ny"])
-- подавление формата для локальных тестов
local wd, wm, wy = true, true, true
local yearmark = "года"
local ym = args["yearmark"] or ((mw.ustring.match((args[3] or ""),"(%a+)") or mw.ustring.match((args[6] or ""),"(%a+)")) or "")
-- mw.log("ym " .. ym)
if yesno(ym) then
elseif yesno(ym) == false then yearmark = ""
else
if not not ym:match("(%d+)") then
error("Цифры в обозначении года: " .. ym)
else yearmark = trim(ym) or "года" end
end
if isdate(ingdate) or isdate(injdate) then
if isdate(ingdate) then
j1date, g1date = recalc(ingdate,"g")
ingdate["full"] = true
end
if isdate(injdate) then
j2date, g2date = recalc(injdate,"j")
injdate["full"] = true
end
if ispartdate(ingdate) and ispartdate(injdate) then
mw.log("📏 " .. dmdist(ingdate,injdate))
mw.log("📏 " .. dmdist(j1date,g1date))
mw.log("📏 " .. dmdist(j2date,g2date))
mw.log("📏 " .. dmdist(ingdate,g1date))
mw.log("📏 " .. dmdist(injdate,j2date))
end
end
if ny then
if isyear(j1date) then
else j1date["year"] = "" end
if isyear(j2date) == nil then
else j2date["year"] = "" end
if isyear(g1date) == nil then
else g1date["year"] = "" end
if isyear(g2date) == nil then
else g2date["year"] = "" end
end
if (isdate(j1date) and isdate(g1date) and isdate(j2date) and isdate(g2date)) then
if ((j1date.year == j2date.year)
and (j1date.month == j2date.month)
and (j1date.day == j2date.day)) then
return double_couple(j1date, g1date, wd, wm, wy, sq_brts, yearmark)
else
mw.log("📏 " .. (tostring(dmdist(ingdate,injdate)) or ""))
return glue(args[1],args[2],args[3],args[4],args[5],args[6])
-- категория (предположительная разница в днях) и частичный вывод
end
elseif isdate(j1date) and isdate(g1date) then
return double_couple(j1date, g1date, wd, wm, wy, sq_brts, yearmark) -- категория плюс частичная проверка
elseif isdate(j2date) and isdate(g2date) then
return double_couple(j2date, g2date, wd, wm, wy, sq_brts, yearmark) -- категория плюс частичная проверка
elseif (ispartdate(ingdate) and ispartdate(injdate)) then
mw.log("ingdate ".. (undate(ingdate) or ""))
mw.log("injdate ".. (undate(injdate) or ""))
mw.log("j1date " .. (undate(j1date ) or ""))
mw.log("j2date " .. (undate(j2date ) or ""))
mw.log("g1date " .. (undate(g1date ) or ""))
mw.log("g2date " .. (undate(g2date ) or ""))
mw.log("📏 " .. (tostring(partdist(ingdate,injdate)) or "").. " — " .. (tostring(partdist(injdate,ingdate)) or ""))
return glue(args[1],args[2],args[3],args[4],args[5],args[6])
-- частичный или полный вывод, категория
else
mw.log("ingdate ".. (undate(ingdate) or ""))
mw.log("injdate ".. (undate(injdate) or ""))
mw.log("j1date " .. (undate(j1date ) or ""))
mw.log("j2date " .. (undate(j2date ) or ""))
mw.log("g1date " .. (undate(g1date ) or ""))
mw.log("g2date " .. (undate(g2date ) or ""))
return err .. category.incomplete_parameters
end
end
return p
a4a91f134ad3e3b246b3a6681a4ae438da766df4
Модуль:Infocards
828
277
715
2023-05-29T15:51:46Z
ruwiki>Putnik
0
переиспользование функции форматирования из [[Module:Dates]] для унификации
Scribunto
text/plain
local infocards = {}
local calculateAge = true
local dateCat = require( 'Module:Infocards/dateCat' )
local moduleDates = require( 'Module:Dates' )
--[[
Helper function that populates the argument list given that user may need to use a mix of
named and unnamed parameters. This is relevant because named parameters are not
identical to unnamed parameters due to string trimming, and when dealing with strings
we sometimes want to either preserve or remove that whitespace depending on the application.
]]
function infocards._getParameters( frame_args, arg_list )
local new_args = {}
local index = 1
local value
for i,arg in ipairs( arg_list ) do
value = frame_args[arg]
if value == nil then
value = frame_args[index]
index = index + 1
end
new_args[arg] = value
end
return new_args
end
function infocards.isBlank( someString )
return someString == nil or mw.ustring.match(someString, '^%s*$') ~= nil
end
function infocards.isDate ( frame )
local new_args = infocards._getParameters( frame.args, {'s', 't', 'f'} )
local s = new_args['s'] or ''
local t = new_args['t'] or ''
local f = new_args['f'] or ''
local result = infocards.isDateImpl ( s )
if (result) then
return t
else
return f
end
end
function infocards.isDateImpl ( s )
local converted = infocards.convertToDate ( s )
return converted ~= nil
end
function infocards.dateOfBirth( frame )
local new_args = infocards._getParameters( frame.args, {'dateOfBirth', 'dateOfDeath', 'suppressAge', 'nocat'} )
local dateOfBirth = new_args['dateOfBirth'] or ''
local dateOfDeath = new_args['dateOfDeath'] or ''
local suppressAge = new_args['suppressAge'] or ''
local nocat = new_args['nocat'] or mw.title.getCurrentTitle().nsText
return infocards.dateOfBirthImpl( dateOfBirth, dateOfDeath, suppressAge, nocat )
end
function infocards.dateOfBirthImpl( dateOfBirth, dateOfDeath, suppressAge, nocat )
local appendToCategory = infocards.isBlank( nocat )
if ( infocards.isBlank( dateOfBirth ) ) then
if ( appendToCategory ) then
return dateCat.categoryNoBirthDate
else
return ''
end
end
if ( mw.ustring.match( dateOfBirth, '^%s*неизвестн.%s*$' ) ~= nil
or mw.ustring.match( dateOfBirth, '^%s*%?%s*$' ) ~= nil ) then
if ( appendToCategory ) then
return "''неизвестно''" .. dateCat.categoryUnknownBirthDate
else
return "''неизвестно''"
end
end
local appendAge = not (suppressAge ~= '' or not calculateAge) and infocards.isBlank( dateOfDeath )
local parsedDate = infocards.convertToDate ( dateOfBirth )
if ( parsedDate == nil ) then
--[[ Temporary hack in order to enable export dates to wikidata ]]
local bDateStart = '<span class="no-wikidata" data-wikidata-property-id="P569">'
local bDateEnd = '</span>'
if ( appendToCategory ) then
return bDateStart .. dateOfBirth .. bDateEnd .. dateCat.categoryManualWikification
else
return bDateStart .. dateOfBirth .. bDateEnd
end
end
local result = infocards.formatDateImpl ( parsedDate, 'bday', appendToCategory and 'Родившиеся' or nil )
if ( appendAge ) then
-- TODO: месяцы и дни для (нескольких) новорождённых (см. новейшие [[Категория:Родившиеся в ГГГГ году]])
local age = infocards.age ( parsedDate, os.date("*t") )
if ( age and age < 125) then
result = result .. ' <span class="nowrap">(' .. age .. ' ' .. mw.language.new( 'ru' ):plural( age, 'год', 'года', 'лет') .. ')</span>'
end
if ( appendToCategory ) then
if (not age and parsedDate and parsedDate.year ) then
age = os.date('*t').year - parsedDate.year -- при неточной дате
end
if ( age ) then
if ( age > 115 ) then
result = result .. dateCat.categoryBigCurrentAge
elseif ( age >= 0 ) then
result = result .. dateCat.categoryBiographiesOfLivingPersons
else
result = result .. dateCat.categoryNegativeAge
end
end
end
end
return result
end
function infocards.dateOfDeath( frame )
local new_args = infocards._getParameters( frame.args, {'dateOfBirth', 'dateOfDeath', 'nocat'} )
local dateOfBirth = new_args['dateOfBirth'] or ''
local dateOfDeath = new_args['dateOfDeath'] or ''
local nocat = new_args['nocat'] or mw.title.getCurrentTitle().nsText
return infocards.dateOfDeathImpl( dateOfBirth, dateOfDeath, nocat )
end
function infocards.dateOfDeathImpl( dateOfBirth, dateOfDeath, nocat )
if ( infocards.isBlank( dateOfDeath ) ) then
return ''
end
local appendToCategory = infocards.isBlank( nocat )
if ( mw.ustring.match( dateOfDeath, '^%s*неизвестн.%s*$' ) ~= nil
or mw.ustring.match( dateOfDeath, '^%s*%?%s*$' ) ~= nil ) then
if ( appendToCategory ) then
return "''неизвестно''" .. dateCat.categoryUnknownDeathDate
else
return "''неизвестно''"
end
end
local parsedDateOfBirth = infocards.convertToDate ( dateOfBirth )
local parsedDateOfDeath = infocards.convertToDate ( dateOfDeath )
if ( parsedDateOfDeath == nil ) then
--[[ Temporary hack in order to enable export dates to wikidata ]]
local dDateStart = '<span class="no-wikidata" data-wikidata-property-id="P570">'
local dDateEnd = '</span>'
if ( appendToCategory ) then
return dDateStart .. dateOfDeath .. dDateEnd .. dateCat.categoryManualWikification
else
return dDateStart .. dateOfDeath .. dDateEnd
end
end
local result = infocards.formatDateImpl ( parsedDateOfDeath, 'dday', appendToCategory and 'Умершие' or nil )
if ( calculateAge ) then
local age = infocards.age ( parsedDateOfBirth, parsedDateOfDeath )
if ( age and age > 0 ) then
result = result .. ' <span class="nowrap">(' .. age .. ' ' .. mw.language.new( 'ru' ):plural( age, 'год', 'года', 'лет') .. ')</span>'
end
-- returns category to recently deceased persons
local unixAvailable, unixDateOfDeath = pcall(function()
local r = os.time(parsedDateOfDeath)
if ( r ~= os.time() ) then
return r
end
error()
end)
if (appendToCategory) then
if ( unixAvailable and os.time() - unixDateOfDeath < 31536000 ) then
result = result .. dateCat.categoryRecentlyDeceased
elseif (age and age < 0) then
result = result .. dateCat.categoryNegativeAge
end
end
end
return result
end
function infocards.age( parsedBirthDate, parsedFinishDate )
if ( parsedBirthDate == nil or parsedFinishDate == nil ) then
return nil
end
local bd = parsedBirthDate["day"]
local bm = parsedBirthDate["month"]
local by = parsedBirthDate["year"]
local dd = parsedFinishDate["day"]
local dm = parsedFinishDate["month"]
local dy = parsedFinishDate["year"]
if ( bd and bm and by and dd and dm and dy ) then
if ( dm > bm or ( dm == bm and dd >= bd ) ) then
return dy - by
else
return dy - by - 1
end
else
return nil
end
end
function infocards.formatDateImpl( parsedDate, infocardClass, categoryNamePrefix )
local datePart = '<span class="nowrap">'
--Temporary hack in order to enable export dates to wikidata
if infocardClass == "bday" then
datePart = '<span class="no-wikidata" data-wikidata-property-id="P569">'
elseif infocardClass == "dday" then
datePart = '<span class="no-wikidata" data-wikidata-property-id="P570">'
end
local t1 = { day = parsedDate.osday, month = parsedDate.osmonth, year = parsedDate.osyear }
local t2 = { day = parsedDate.day, month = parsedDate.month, year = parsedDate.year }
datePart = datePart .. moduleDates.formatWikiImpl( t1, t2, infocardClass, categoryNamePrefix )
datePart = datePart .. '</span>'
return datePart
end
function infocards.convertToDate( possibleDateString )
possibleDateString = mw.ustring.gsub( possibleDateString, '−', '-')
local simpleDate = mw.ustring.match(possibleDateString, '^%s*([%-%d%.]+)%s*$', 0)
if ( simpleDate ) then
return infocards.convertToDateNewStylePart( simpleDate )
end
local complexDate1, complexDate2 = mw.ustring.match(possibleDateString, '^%s*([%-%d%.]+)%s*%(([%-%d%.]+)%)%s*$', 0)
if ( complexDate1 and complexDate2) then
local table1 = infocards.convertToDateNewStylePart( complexDate1 )
local table2 = infocards.convertToDateOldStylePart( complexDate2 )
if ( table1 and table2 ) then
return {
year = table1["year"], month = table1["month"], day = table1["day"],
osyear = table2["year"], osmonth = table2["month"], osday = table2["day"]
}
else
return nil
end
end
return nil
end
function infocards.convertToDateNewStylePart( possibleDateString )
local ny = mw.ustring.match(possibleDateString, '^(%-?%d+)$', 0)
if (ny ~= nil) then
return {year = tonumber(ny)}
end
return infocards.convertToDateCommonPart( possibleDateString )
end
function infocards.convertToDateOldStylePart( possibleDateString )
local nd = mw.ustring.match(possibleDateString, '^(%-?%d+)$', 0)
if (nd ~= nil) then
return {day = tonumber(nd)}
end
return infocards.convertToDateCommonPart( possibleDateString )
end
function infocards.convertToDateCommonPart( possibleDateString )
local sDay, sMonth, sYear
local day, month, year
sDay, sMonth, sYear = mw.ustring.match( possibleDateString, '^(%d?%d)%.(%d?%d)%.(%-?%d+)$', 0 )
if sDay ~= nil and sMonth ~= nil and sYear ~= nil then
day = tonumber( sDay )
month = tonumber( sMonth )
year = tonumber( sYear )
if day >= 1 and day <= 32 and month >= 1 and month <= 12 then
return { day = day, month = month, year = year }
end
end
sDay, sMonth = mw.ustring.match( possibleDateString, '^(%d?%d)%.(%d?%d+)$', 0 )
if sDay ~= nil and sMonth ~= nil then
day = tonumber( sDay )
month = tonumber( sMonth )
if day >= 1 and day <= 32 and month >= 1 and month <= 12 then
return { day = day, month = month }
end
end
sMonth, sYear = mw.ustring.match( possibleDateString, '^(%d?%d)%.(%-?%d+)$', 0 )
if sMonth ~= nil and sYear ~= nil then
month = tonumber( sMonth )
year = tonumber( sYear )
if month >= 1 and month <= 12 then
return { month = month, year = year }
end
end
return nil
end
return infocards
6c1e746d6605d4d101f6aa9fd3e4824b60c64ef7
Шаблон:Число
10
160
362
2023-06-20T10:24:09Z
ruwiki>Stjn
0
лучше так тогда для лимитов
wikitext
text/x-wiki
{{formatnum: {{replace|{{{1}}}|,|.}} }}{{#if: {{{1|}}} | {{#if: {{{2|}}} | {{nobr|1= {{{2|}}}}} }} }}<noinclude>
{{doc}}
</noinclude>
acfc1e9cec817e6742b18106f020ac388ececc7e
Шаблон:Карточка/оригинал имени
10
268
697
2023-07-04T10:53:34Z
ruwiki>Wikisaurus
0
wikitext
text/x-wiki
{{wikidata|p1559[language!:ru]|{{{1|}}}|before={{{before|}}}|separator=<br>|conjunction=<br>|monolingualLangTemplate={{{monolingualLangTemplate|lang}}}|from={{{from|}}}}}<!--
-->{{#if:{{NAMESPACE}}||{{#if:{{{1|}}}|{{#ifeq:{{#invoke:String|find|{{{1|}}}|span}}|0|[[Категория:Википедия:Статьи с оригиналом имени без шаблона lang-XX]]}}}}}}<noinclude>{{doc}}</noinclude>
a294e3f7f61c5206ca5671b72e21804d7a32fcbc
Шаблон:Карточка/оригинал названия
10
154
350
2023-07-04T10:53:52Z
ruwiki>Wikisaurus
0
wikitext
text/x-wiki
{{wikidata|p1705[language!:ru]|{{{1|}}}|separator=<br>|conjunction=<br>|monolingualLangTemplate=lang|from={{{from|}}}}}<!--
-->{{#if:{{NAMESPACE}}||{{#if:{{{1|}}}|{{#ifeq:{{#invoke:String|find|{{{1|}}}|span}}|0|[[Категория:Википедия:Статьи с оригиналом названия без шаблона lang-XX]]}}}}}}<noinclude>{{doc}}</noinclude>
4eccda042428e1113ff320ff5d6b760a7f52b088
Шаблон:Государство
10
122
286
2023-07-18T14:45:13Z
ruwiki>Krestenti
0
wikitext
text/x-wiki
{{Карточка
|имя = Государство
|автозаголовки = да
|from = {{{from|}}}
|вверху0 = {{#switch: {{{Статус|}}}
| виртуальное = [[Виртуальное государство]]
| особый = {{#if: {{{Спорный статус|}}} | {{{Особый спорный статус|}}} }}
| Непризнанное
| непризнанное = {{#if: {{{Спорный статус|}}} | [[Непризнанные и частично признанные государства|Непризнанное государство]] }}
| Частично признанное
| частично признанное = {{#if: {{{Спорный статус|}}} | [[Непризнанные и частично признанные государства|Частично признанное государство]] }}
}}
|вверху = {{карточка/название|{{{Русское название|}}}|from={{{from|}}}}}
|вверху2 = {{карточка/оригинал названия|{{карточка/официальное название|{{{Оригинальное название|}}}|from={{{from|}}}}}|from={{{from|}}}}}
|изображение = {{Карточка/флаг и герб
| флаг = {{{Флаг|}}}
| флаг ширина = {{{Размер флага|}}}{{{размер флага|}}}
| флаг подпись = [[{{#if: {{{Ссылка на флаг|}}} | {{{Ссылка на флаг}}} | Флаг {{{Родительный падеж}}} }}|Флаг]]
| герб = {{{Герб|}}}
| герб ширина = {{{Размер герба|}}}{{{размер герба|}}}
| герб подпись = {{#if: {{{Отображаемая подпись герба|}}} | {{{Отображаемая подпись герба}}} | {{#if: {{{Вместо герба|}}} | [[{{{Вместо герба}}} {{{Родительный падеж}}}|{{{Вместо герба}}}]] | [[Герб {{{Родительный падеж}}}|Герб]] }} }}
|from={{{from|}}}}}
|текст1 = {{br separated entries
| {{#if: {{{Девиз|}}} | [[Девиз]]: ''«{{{Девиз}}}»'' }}
| {{#if: {{{Перевод девиза|}}} | ''«{{{Перевод девиза}}}»'' }}
}}
|текст2 = {{#if: {{{Без гимна|}}} || {{#if: {{{Название гимна|}}} | {{br separated entries | [[Государственный гимн|Гимн]]: [[Гимн {{{Родительный падеж}}}|''«{{{Название гимна}}}»'']] | {{#if: {{{Перевод названия гимна|}}} | ''«{{{Перевод названия гимна}}}»'' }} }} | [[Гимн {{{Родительный падеж<noinclude>|</noinclude>}}}|Государственный гимн {{{Родительный падеж<noinclude>|</noinclude>}}}]] }}{{#if: {{{Аудио|}}} | {{#if: {{{Аудио|}}} | [[Файл:{{{Аудио|}}}|center]] }} }} }}
|текст3 = {{#if: {{wikidata|p242|{{{На карте|}}}|plain=true|from={{{from|}}}}} | {{wikidata|p242|{{{На карте|}}}|size={{#if: {{{Размер карты|}}}{{{размер карты|}}} | {{{Размер карты|}}}{{{размер карты|}}} | 300x300px }}|caption={{{Подпись к карте|}}}{{{подпись к карте|}}}|from={{{from|}}}}}<!--
-->{{#if: {{{На карте2|}}} | <br>[[Файл:{{{На карте2}}}|{{{Размер карты2|{{{размер карты2|300x300px}}}}}}]]{{#if:{{{Подпись к карте 2|}}}{{{подпись к карте 2|}}}|<br>{{{Подпись к карте 2|{{{подпись к карте 2|}}}}}} }} }} }}
|заголовок4 = {{#if: {{{sovereignty_type|}}} | {{{sovereignty_type}}} | [[История {{{Родительный падеж}}}|История]] }}
|стиль_заголовка4 = padding-bottom:0; border-bottom:0; text-align:left;
|блок5 =
{{Карточка/блок с маркерами
|метка1 = {{nobr|{{{Дата1}}}}}
|текст1 = {{{Этап1|}}}
|метка2 = {{nobr|{{{Дата2}}}}}
|текст2 = {{{Этап2|}}}
|метка3 = {{nobr|{{{Дата3}}}}}
|текст3 = {{{Этап3|}}}
|метка4 = {{nobr|{{{Дата4}}}}}
|текст4 = {{{Этап4|}}}
|метка5 = {{nobr|{{{Дата5}}}}}
|текст5 = {{{Этап5|}}}
|метка6 = {{nobr|{{{Дата6}}}}}
|текст6 = {{{Этап6|}}}
|метка7 = {{nobr|{{{Дата7}}}}}
|текст7 = {{{Этап7|}}}
|метка8 = {{nobr|{{{Дата8}}}}}
|текст8 = {{{Этап8|}}}
|метка9 = {{nobr|{{{Дата9}}}}}
|текст9 = {{{Этап9|}}}
|метка10 = {{nobr|{{{Дата10}}}}}
|текст10 = {{{Этап10|}}}
|метка11 = {{nobr|{{{Дата11}}}}}
|текст11 = {{{Этап11|}}}
|метка12 = {{nobr|{{{Дата12}}}}}
|текст12 = {{{Этап12|}}}
|from={{{from|}}}}}
|заголовок6 = -
|метка7 = [[Основание государства|{{#if: {{{Основана|}}} | Основана | Основано }}]]
|текст7 = {{{Основана|}}}{{{Основано|}}}
|викиданные7 =
<!-- СПОРНЫЙ СТАТУС -->
<!-- Спорный статус заполнен -->
|метка8 = [[Основание государства|Дата образования]]
|текст8 = {{#if: {{{Спорный статус|}}} | {{{Дата образования|}}} }}
|викиданные8 =
|метка9 = Провозглашение независимости
|текст9 = {{#if: {{{Спорный статус|}}} | {{#if: {{{Провозглашение независимости|}}} | {{{Провозглашение независимости}}} {{#if: {{{Независимость от|}}} | (от {{{Независимость от}}}) }} }} }}
|викиданные9 =
|метка10 = [[Международно-правовое признание|Дипломатическое признание]]
|текст10 = {{#if: {{{Спорный статус|}}} | {{{Дипломатическое признание|}}} }}
|викиданные10 =
<!-- Спорный статус не заполнен -->
|метка11 = {{#if: {{{Отображаемый тип независимости|}}} | {{{Отображаемый тип независимости}}} | [[Суверенитет|{{#if: {{{Даты независимости|}}} | Даты | Дата }} независимости]] }}
|текст11 = {{#if: {{{Спорный статус|}}} || {{#if: {{{Дата независимости|}}}{{{Даты независимости|}}} | {{{Дата независимости|{{{Даты независимости|}}}}}} {{#if: {{{Независимость от|}}} | (от {{{Независимость от}}}) }} }} }}
|викиданные11 =
<!-- / СПОРНЫЙ СТАТУС -->
|метка12 = [[Официальный язык|{{#if: {{{Язык|}}} | Официальный язык | Официальные языки }}]]
|текст12 = {{{Язык|{{{Языки|}}}}}}
|викиданные12 = p37
|метка13 = [[Столица]]
|текст13 = {{{Столица|}}}
|викиданные13 = p36
|метка14 = {{#if: {{{Крупнейший город|}}} | Крупнейший город | Крупнейшие города }}
|текст14 = {{{Крупнейший город|}}}{{{Крупнейшие города|}}}
|викиданные14 =
|метка15 = [[Форма государственного правления|Форма правления]]
|текст15 = {{{Форма правления|}}}
|викиданные15 =
|метка16 = [[Форма государственного устройства|Государственный строй]]
|текст16 = {{{Государственный строй|}}}
|метка17 = {{{Должность руководителя 1|{{{Должности руководителей}}}}}}
|текст17 = {{{Руководитель 1|{{{Руководители|}}}}}}
|метка18 = {{{Должность руководителя 2}}}
|текст18 = {{{Руководитель 2|}}}
|метка19 = {{{Должность руководителя 3}}}
|текст19 = {{{Руководитель 3|}}}
|метка20 = {{{Должность руководителя 4}}}
|текст20 = {{{Руководитель 4|}}}
|метка21 = {{{Должность руководителя 5}}}
|текст21 = {{{Руководитель 5|}}}
|метка22 = {{{Должность руководителя 6}}}
|текст22 = {{{Руководитель 6|}}}
|метка23 = [[Государственная религия|Гос. религия]]
|текст23 = {{{Государственная религия|}}}
|викиданные23 =
|блок24 =
{{Карточка/блок с маркерами
|подзаголовок = [[Территория государства|Территория]]
|метка1 = Всего
|текст1 = {{br separated entries
| {{число|{{{Территория|}}}|км²}}{{#if: {{{Место по территории|}}} | {{nobr|([[Список государств и зависимых территорий по площади|{{{Место по территории}}}-я в мире]])}} }}
| {{число|{{{Территория2|}}}|км²}}
}}
|метка2 = % водной поверхности
|текст2 = {{#ifeq: {{{Процент воды|}}} | - || {{{Процент воды|}}} }}
|from={{{from|}}}}}
|блок25 =
{{Карточка/блок с маркерами
|подзаголовок = [[{{Население государства|{{PAGENAME}}}}]]
|метка1 = Оценка {{#if: {{{Год оценки|}}} | ({{{Год оценки}}}) }}
|текст1 = {{br separated entries
| {{число|{{{Население|}}}|чел.}}{{#if: {{{Место по населению|}}} | ([[Список стран по населению|{{{Место по населению}}}-е]]) }}
| {{число|{{{Население2|}}}|чел.}}
}}
|метка2 = Перепись {{#if: {{{Год переписи|}}} | ({{{Год переписи}}}) }}
|текст2 = {{число|{{{Население по переписи|}}}|чел.}}
|метка3 = [[Плотность населения|Плотность]]
|текст3 = {{число|{{{Плотность населения|}}}|чел./км²}}{{#if: {{{Место по плотности|}}} | ([[Список стран по плотности населения|{{{Место по плотности}}}-я]]) }}
|from={{{from|}}}}}
|блок26 =
{{Карточка/блок с маркерами
|подзаголовок = [[Валовой внутренний продукт|ВВП]]
|метка1 = Итого {{#if: {{{Год расчёта ВВП|}}} | ({{{Год расчёта ВВП}}}) }}
|текст1 = {{число|{{{ВВП|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП|}}} | ([[Список стран по ВВП (ППС)|{{{Место по ВВП}}}-й]]) }}
|метка2 = На душу населения
|текст2 = {{число|{{{ВВП на душу населения|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП на душу населения|}}} | ([[Список стран по ВВП (ППС) на душу населения|{{{Место по ВВП на душу населения}}}-й]]) }}
|from={{{from|}}}}}
|блок27 =
{{Карточка/блок с маркерами
|подзаголовок = [[Валовой внутренний продукт|ВВП]] <span style="font-weight:normal;">([[Паритет покупательной способности|ППС]])</span>
|метка1 = Итого {{#if: {{{Год расчёта ВВП (ППС)|}}} | ({{{Год расчёта ВВП (ППС)}}}) }}
|текст1 = {{число|{{{ВВП (ППС)|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (ППС)|}}} | ([[Список стран по ВВП (ППС)|{{{Место по ВВП (ППС)}}}-й]]) }}
|метка2 = На душу населения
|текст2 = {{число|{{{ВВП (ППС) на душу населения|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (ППС) на душу населения|}}} | ([[Список стран по ВВП (ППС) на душу населения|{{{Место по ВВП (ППС) на душу населения}}}-й]]) }}
|from={{{from|}}}}}
|блок28 =
{{Карточка/блок с маркерами
|подзаголовок = [[Валовой внутренний продукт|ВВП]] <span style="font-weight:normal;">(номинал)</span>
|метка1 = Итого {{#if: {{{Год расчёта ВВП (номинал)|}}} | ({{{Год расчёта ВВП (номинал)}}}) }}
|текст1 = {{число|{{{ВВП (номинал)|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (номинал)|}}} | ([[Список стран по ВВП (номинал)|{{{Место по ВВП (номинал)}}}-й]]) }}
|метка2 = На душу населения
|текст2 = {{число|{{{ВВП (номинал) на душу населения|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (номинал) на душу населения|}}} | ([[Список стран по ВВП (номинал) на душу населения|{{{Место по ВВП (номинал) на душу населения}}}-й]]) }}
|from={{{from|}}}}}
|метка29 = [[Индекс человеческого развития|ИЧР]] {{#if: {{{Год расчёта ИРЧП|}}} | <span style="font-weight:normal;">({{{Год расчёта ИРЧП}}})</span> }}
|текст29 = {{{ИРЧП|}}}{{#if: {{{Уровень ИРЧП|}}} | ({{{Уровень ИРЧП}}}{{#if: {{{Место по ИРЧП|}}} | ; [[Список стран по индексу человеческого развития|{{{Место по ИРЧП}}}-е место]] }}) }}
|викиданные29 =
|метка30 = [[Названия жителей]]
|текст30 = {{{Этнохороним|}}}
|викиданные30 =
|метка31 = [[Валюта]]
|текст31 = {{{Валюта|}}}
|викиданные31 = P38
|метка32 = [[Домен верхнего уровня|{{wikidata number switch|P78|{{{Домен|}}}|{{{Домены|}}}|Интернет-домен|Интернет-домены}}]]
|текст32 = {{{Домен|}}}{{{Домены|}}}
|викиданные32 = P78
|метка33 = [[ISO 3166-1|Код ISO]]
|текст33 =
|викиданные33 = P297
|метка34 = [[Список кодов МОК|Код МОК]]
|текст34 =
|викиданные34 = P984
|метка35 = [[Список телефонных кодов стран|Телефонный код]]
|текст35 = {{#if: {{{Телефонный код|}}} | {{#ifeq: {{{Телефонный код|}}} | - | - | +{{{Телефонный код}}} }} }}
|викиданные35 = P474
|метка36 = [[Часовой пояс|{{wikidata number switch|P421|{{{Часовой пояс|}}}|{{{Часовые пояса|}}}|Часовой пояс|Часовые пояса}}]]
|текст36 = {{{Часовой пояс|}}}{{{Часовые пояса|}}}
|викиданные36 = P421
|метка37 = Автомобильное движение
|текст37 = {{{Автомобильное движение|}}}
|викиданные37 = P1622
|текст38 = {{{Примечания|}}}
|стиль_текста38 = border-top:1px solid #a2a9b1; color:#54595d; padding-top:0.5em; text-align:left;
|внизу = {{карточка/Викисклад|from={{{from|}}}}}
}}{{#if: {{{nocat|}}}{{NAMESPACE}} || <!--
-->{{#if: {{{lat_deg|}}}
| {{coord|1={{{lat_deg|}}}|2={{{lat_min|0}}}|3={{{lat_sec|0}}}|4={{#if: {{{lat_dir|}}} | {{{lat_dir}}} | N }}|5={{{lon_deg|}}}|6={{{lon_min|0}}}|7={{{lon_sec|0}}}|8={{#if: {{{lon_dir|}}} | {{{lon_dir}}} | E }}|type=country|region={{{region|}}}|scale={{{CoordScale|}}}|format=dms|display=title}}
| {{#if: {{#property: p625}} | {{wikidata|p625|type=country|region={{{region|}}}|scale={{{CoordScale|}}}|from={{{from|}}}}} | [[Категория:Государства без указанных географических координат]] }}
}}<!--
-->{{#switch: {{{Статус|}}}
| Виртуальное
| виртуальное = [[Категория:Виртуальные государства]]
| Непризнанное
| непризнанное = [[Категория:Непризнанные государства]]
| Частично признанное
| частично признанное = [[Категория:Частично признанные государства]]
| особый = {{#if: {{{Спорный статус|}}} | {{#if: {{{Особая категория|}}}|[[Категория:{{{Особая категория|}}}]]|[[Категория:Государства по алфавиту]]}} }}
| [[Категория:Государства по алфавиту]]
}}<!--
-->{{Государство/Викиданные}}
}}<noinclude>{{doc}}</noinclude>
d5532838af5967020fc4f653452458ba05aea4cf
Шаблон:Государство/doc
10
184
410
2023-10-11T16:26:29Z
ruwiki>CyberNik01
0
wikitext
text/x-wiki
{{docpage}}
Этот [[Википедия:Шаблоны-карточки|шаблон-карточка]] используется для вставки карточки в статьи о современных государствах;
* для исторических государств используйте {{t|историческое государство}}.
* для составных частей государств используйте {{t|Административная единица}}.
== Образец для копирования ==
<pre>
{{Государство
|Статус = <!-- виртуальное / непризнанное / частично признанное / регион; для признанных государств не заполнять -->
|Русское название =
|Оригинальное название =
|Родительный падеж =
|Герб =
|Вместо герба =
|Девиз = {{lang-??2|}}<!-- на оф. языке / языках гос-ва -->
|Перевод девиза =
|Название гимна =
|Перевод названия гимна =
|Аудио =
|Форма правления =
|Государственный строй =
|Государственная религия =
|На карте =
|подпись к карте =
|На карте2 =
|Язык/Языки =
|Основано/Основана =
|Дата/Даты независимости =
|Независимость от =
|Столица =
|Крупнейшие города =
|Должность руководителя 1 =
|Руководитель 1 =
|Должность руководителя 2 =
|Руководитель 2 =
|Должность руководителя 3 =
|Руководитель 3 =
|Должность руководителя 4 =
|Руководитель 4 =
|Должность руководителя 5 =
|Руководитель 5 =
|Место по территории =
|Территория =
|Процент воды =
|Этнохороним =
|Место по населению =
|Население =
|Год оценки =
|Население по переписи =
|Год переписи =
|Плотность населения =
|Место по плотности =
|ВВП (ППС) =
|Год расчёта ВВП (ППС) =
|Место по ВВП (ППС) =
|ВВП (ППС) на душу населения =
|Место по ВВП (ППС) на душу населения =
|ВВП (номинал) =
|Год расчёта ВВП (номинал) =
|Место по ВВП (номинал) =
|ВВП (номинал) на душу населения =
|Место по ВВП (номинал) на душу населения =
|ИРЧП =
|Год расчёта ИРЧП =
|Место по ИРЧП =
|Уровень ИРЧП =
|Валюта =
|Домен/Домены =
|Телефонный код =
|Часовой пояс =
|Автомобильное движение =
|Примечания =
<!-- |Без флага и герба=* -->
<!-- |Без гимна=* -->
}}
</pre>
== Описание параметров ==
Некоторые параметры могут быть заданы в разных формах (например, в единственном либо множественном числе). После копирования образца в статью заполните только строку с более подходящей формой. Например, в статье [[Албания]] —
<pre> |Язык = [[Албанский язык|албанский]]</pre>
а в статье [[Канада]] —
<pre> |Языки = [[Английский язык|английский]] и [[Французский язык|французский]]</pre>
Для статей о регионах с нечётким правовым статусом используйте параметр <code>Спорный статус = да</code> и параметры «Основано», «Дата образования», «Провозглашение независимости» и «Дипломатическое признание» вместо «Дата независимости» и «Основано»:
<pre>
|Спорный статус = да
|Основано =
|Основана =
|Дата образования =
|Провозглашение независимости =
|Дипломатическое признание =
|Независимость от =
</pre>
Для статей о [[Непризнанные и частично признанные государства|непризнанных государствах]] или [[Автономный регион|автономных регионах]], не являющихся самостоятельными государствами, используйте параметр <code>Статус = непризнанное</code> или <code>Статус = регион</code>, это отключит автоматическое добавление категории [[:Категория:Государства по алфавиту|Государства по алфавиту]], а в первом случае также добавит категорию [[:Категория:Непризнанные государства|Непризнанные государства]]. Для статей о [[Виртуальное государство|виртуальных государствах]] используйте параметр <code>Статус = виртуальное</code>, это добавит категорию [[:Категория:Виртуальные государства|Виртуальные государства]].
== Пример использования ==
{{demo|reverse=1|br=|<nowiki>{{Государство
|Русское название = Финляндская Республика
|Оригинальное название = {{lang-fi|Suomen Tasavalta}}<br>{{lang-sv|Republiken Finland}}
|Родительный падеж = Финляндии
|Герб = Coat of arms of Finland.svg
|Флаг = Flag of Finland.svg<!-- иначе используется конструкция {{флаг|{{FULLPAGENAME}}|размер=135px}} -->
|Вместо герба =
|Девиз =
|Перевод девиза =
|Название гимна = Maamme
|Перевод названия гимна = Наш край
|Аудио =
|Форма правления = [[президентская республика]]
|Государственный строй = [[унитарное государство]]
|Государственная религия =
|На карте = EU-Finland.svg
|подпись к карте = Расположение '''Финляндии''' (тёмно-зелёный):<br>— в [[Европа|Европе]] (светло-зелёный и тёмно-серый)<br>— в [[Европейский союз|Европейском союзе]] (светло-зелёный)
|На карте2 =
|Языки = [[финский язык|финский]], [[шведский язык|шведский]]
|Основано/Основана =
|Дата независимости = [[6 декабря]] [[1917]]
|Независимость от = [[Россия|России]]
|Столица = [[Хельсинки]]
|Крупнейший город = Хельсинки
|Должность руководителя 1 = [[Президент Финляндии|Президент]]
|Руководитель 1 = [[Халонен, Тарья Каарина|Тарья Халонен]]
|Должность руководителя 2 = [[Премьер-министр Финляндии|Премьер-министр]]
|Руководитель 2 = [[Ванханен, Матти Танели|Матти Ванханен]]
|Место по территории = 63
|Территория = 338 145
|Процент воды = 9,96
|Этнохороним = финляндец, финляндка
|Место по населению = 106
|Население = 5 219 732
|Год оценки = 2003
|Население по переписи =
|Год переписи =
|Плотность населения = 15,4
|Место по плотности =
|ВВП =
|Год расчёта ВВП =
|Место по ВВП =
|ВВП на душу населения =
|Место по ВВП на душу населения =
|ИРЧП =
|Год расчёта ИРЧП =
|Место по ИРЧП =
|Уровень ИРЧП =
|Валюта = [[евро]]<ref name="money">до 2002 — [[финская марка]]</ref>
|Домены = [[.fi]], [[.ax]] (для [[Аландские острова|Аландских островов]])
|Телефонный код = 358
|Часовой пояс = +2
|Автомобильное движение =
|Примечания = <references/>
}}</nowiki>}}
== TemplateData ==
<templatedata>
{
"params": {
"Спорный статус": {},
"Статус": {},
"Русское название": {},
"Оригинальное название": {},
"Флаг": {
"type": "wiki-file-name"
},
"Ссылка на флаг": {},
"Родительный падеж": {},
"Герб": {
"type": "wiki-file-name"
},
"Отображаемая подпись герба": {},
"Вместо герба": {},
"Девиз": {},
"Перевод девиза": {},
"Без гимна": {},
"Название гимна": {},
"Перевод названия гимна": {},
"Аудио": {},
"На карте": {},
"На карте2": {},
"Дата1": {},
"Дата2": {},
"Дата3": {},
"Дата4": {},
"Дата5": {},
"Дата6": {},
"Дата7": {},
"Дата8": {},
"Дата9": {},
"Дата10": {},
"Дата11": {},
"Дата12": {},
"sovereignty_type": {},
"Этап1": {},
"Этап2": {},
"Этап3": {},
"Этап4": {},
"Этап5": {},
"Этап6": {},
"Этап7": {},
"Этап8": {},
"Этап9": {},
"Этап10": {},
"Этап11": {},
"Этап12": {},
"Основана": {},
"Основано": {},
"Дата образования": {},
"Провозглашение независимости": {},
"Независимость от": {},
"Дипломатическое признание": {},
"Отображаемый тип независимости": {},
"Даты независимости": {},
"Дата независимости": {},
"Язык": {},
"Языки": {},
"Столица": {},
"Крупнейший город": {},
"Крупнейшие города": {},
"Форма правления": {},
"Должность руководителя 1": {},
"Должности руководителей": {},
"Руководитель 1": {},
"Руководители": {},
"Должность руководителя 2": {},
"Руководитель 2": {},
"Должность руководителя 3": {},
"Руководитель 3": {},
"Должность руководителя 4": {},
"Руководитель 4": {},
"Должность руководителя 5": {},
"Руководитель 5": {},
"Государственная религия": {},
"Место по территории": {},
"Территория": {},
"Процент воды": {},
"Территория2": {},
"Население": {},
"Год оценки": {},
"Год переписи": {},
"Население2": {},
"Место по населению": {},
"Население по переписи": {},
"Плотность населения": {},
"Место по плотности": {},
"ВВП": {},
"Год расчёта ВВП": {},
"Место по ВВП": {},
"ВВП на душу населения": {},
"Место по ВВП на душу населения": {},
"ВВП (ППС)": {},
"Год расчёта ВВП (ППС)": {},
"Место по ВВП (ППС)": {},
"ВВП (ППС) на душу населения": {},
"Место по ВВП (ППС) на душу населения": {},
"ВВП (номинал)": {},
"Год расчёта ВВП (номинал)": {},
"Место по ВВП (номинал)": {},
"ВВП (номинал) на душу населения": {},
"Место по ВВП (номинал) на душу населения": {},
"Год расчёта ИРЧП": {},
"ИРЧП": {},
"Уровень ИРЧП": {},
"Место по ИРЧП": {},
"Этнохороним": {},
"Валюта": {},
"Домены": {},
"Домен": {},
"Телефонный код": {},
"Часовые пояса": {},
"Часовой пояс": {},
"Примечания": {},
"nocat": {
"type": "boolean"
},
"lat_deg": {},
"lat_min": {},
"lat_sec": {},
"lat_dir": {},
"lon_deg": {},
"lon_min": {},
"lon_sec": {},
"lon_dir": {},
"region": {},
"CoordScale": {},
"Размер герба": {
"aliases": [
"размер герба"
],
"type": "number"
},
"Размер флага": {
"aliases": [
"размер флага"
],
"type": "number"
},
"Размер карты": {
"aliases": [
"размер карты"
]
},
"Подпись к карте": {
"aliases": [
"подпись к карте"
]
},
"Размер карты2": {
"aliases": [
"размер карты2"
]
},
"Государственный строй": {},
"Автомобильное движение": {}
},
"paramOrder": [
"Статус",
"Спорный статус",
"Русское название",
"Оригинальное название",
"Флаг",
"Размер флага",
"Ссылка на флаг",
"Родительный падеж",
"Герб",
"Размер герба",
"Отображаемая подпись герба",
"Вместо герба",
"Девиз",
"Перевод девиза",
"Без гимна",
"Название гимна",
"Перевод названия гимна",
"Аудио",
"На карте",
"Размер карты",
"Подпись к карте",
"На карте2",
"Размер карты2",
"Дата1",
"Дата2",
"Дата3",
"Дата4",
"Дата5",
"Дата6",
"Дата7",
"Дата8",
"Дата9",
"Дата10",
"Дата11",
"Дата12",
"sovereignty_type",
"Этап1",
"Этап2",
"Этап3",
"Этап4",
"Этап5",
"Этап6",
"Этап7",
"Этап8",
"Этап9",
"Этап10",
"Этап11",
"Этап12",
"Основана",
"Основано",
"Дата образования",
"Провозглашение независимости",
"Независимость от",
"Дипломатическое признание",
"Отображаемый тип независимости",
"Даты независимости",
"Дата независимости",
"Язык",
"Языки",
"Столица",
"Крупнейший город",
"Крупнейшие города",
"Форма правления",
"Государственный строй",
"Должность руководителя 1",
"Должности руководителей",
"Руководитель 1",
"Руководители",
"Должность руководителя 2",
"Руководитель 2",
"Должность руководителя 3",
"Руководитель 3",
"Должность руководителя 4",
"Руководитель 4",
"Должность руководителя 5",
"Руководитель 5",
"Государственная религия",
"Место по территории",
"Территория",
"Процент воды",
"Территория2",
"Население",
"Год оценки",
"Год переписи",
"Население2",
"Место по населению",
"Население по переписи",
"Плотность населения",
"Место по плотности",
"ВВП",
"Год расчёта ВВП",
"Место по ВВП",
"ВВП на душу населения",
"Место по ВВП на душу населения",
"ВВП (ППС)",
"Год расчёта ВВП (ППС)",
"Место по ВВП (ППС)",
"ВВП (ППС) на душу населения",
"Место по ВВП (ППС) на душу населения",
"ВВП (номинал)",
"Год расчёта ВВП (номинал)",
"Место по ВВП (номинал)",
"ВВП (номинал) на душу населения",
"Место по ВВП (номинал) на душу населения",
"Год расчёта ИРЧП",
"ИРЧП",
"Уровень ИРЧП",
"Место по ИРЧП",
"Этнохороним",
"Валюта",
"Домены",
"Домен",
"Телефонный код",
"Часовые пояса",
"Часовой пояс",
"Автомобильное движение",
"Примечания",
"lat_deg",
"lat_min",
"lat_sec",
"lat_dir",
"lon_deg",
"lon_min",
"lon_sec",
"lon_dir",
"region",
"CoordScale",
"nocat"
],
"format": "block"
}
</templatedata>
== См. также ==
* {{tl|Историческое государство}}
<includeonly>
[[Категория:Шаблоны-карточки:Географические объекты]]
</includeonly>
b1e2b1107db0671d3bcc4dda5bd29020192c442e
Шаблон:Сначала имя
10
275
711
2023-11-15T18:34:52Z
ruwiki>Stjn
0
читаемость
wikitext
text/x-wiki
{{safesubst:<noinclude />#ifexpr: {{safesubst:<noinclude />str find|{{safesubst:<noinclude />До символа|{{{1}}}|(}}|,}} = -1 <!--
-->|{{safesubst:<noinclude />До символа|{{{1}}}|(}}<!--
-->|{{safesubst:<noinclude />trim|{{safesubst:<noinclude />После символа|{{safesubst:<noinclude />До символа|{{{1}}}|(}}|,}}}} {{safesubst:<noinclude />До символа|{{safesubst:<noinclude />До символа|{{{1}}}|(}}|,}}<!--
-->}}<noinclude>
{{doc}}
</noinclude>
c3a2e3e13dba0ae595a7c147ca692be2eb183f38
Шаблон:Скрытый блок
10
200
446
2023-12-21T00:36:59Z
ruwiki>Stjn
0
неактуальный параметр
wikitext
text/x-wiki
{{Начало скрытого блока
|id = {{{id|}}}
|тип = {{{тип|{{{type|}}}}}}
|состояние = {{{state|{{{состояние|collapsed}}}}}}
|класс_тела = {{{класс_тела|{{{класс тела|}}}}}}
|стиль_тела = {{{frame-style|{{{стиль_тела|{{{стиль тела|}}}}}}}}}
|рамка = {{{Рамка|{{{border|{{{рамка|}}}}}}}}}
|заголовок = {{{Заголовок|{{{заголовок|{{{Заглавие|{{{заглавие|{{{Название|{{{название|{{{header|{{{title|{{{1}}}}}}}}}}}}}}}}}}}}}}}}}}}
|ссылка = {{{Ссылка|{{{ссылка|}}}}}}
|класс_заголовка = {{{класс_заголовка|{{{класс заголовка|}}}}}}
|шрифт_заголовка = {{{Шрифт_заголовка|{{{шрифт_заголовка|{{{шрифт заголовка|}}}}}}}}}
|наклон_заголовка = {{{Наклон_заголовка|{{{наклон_заголовка|{{{наклон заголовка|}}}}}}}}}
|фон_заголовка = {{{Фон_заголовка|{{{bg1|{{{фон_заголовка|{{{фон заголовка|}}}}}}}}}}}}
|выравнивание_заголовка = {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}}
|стиль_заголовка = {{{title-style|{{{Стиль_заголовка|{{{extra1|{{{стиль_заголовка|{{{стиль заголовка|}}}}}}}}}}}}}}}
|класс_текста = {{{класс_текста|{{{класс текста|}}}}}}
|шрифт_текста = {{{Шрифт_текста|{{{шрифт_текста|{{{шрифт текста|}}}}}}}}}
|наклон_текста = {{{Наклон_текста|{{{наклон_текста|{{{наклон текста|}}}}}}}}}
|фон_текста = {{{Фон_текста|{{{bg2|{{{фон_текста|{{{фон текста|}}}}}}}}}}}}
|выравнивание_текста = {{{Выравнивание_текста|{{{ta2|{{{выравнивание_текста|{{{выравнивание текста|}}}}}}}}}}}}
|стиль_текста = {{{content-style|{{{Стиль_текста|{{{extra2|{{{стиль_текста|{{{стиль текста|}}}}}}}}}}}}}}}}}
{{{content|{{{Содержание|{{{содержание|{{{2}}}}}}}}}}}}
{{#if: {{{footer|}}} | <div style="{{{footer-style|{{{title-style|}}}}}}">{{{footer}}}</div> }}
{{Конец скрытого блока}}<noinclude>
{{doc}}
</noinclude>
792dc9fb2eb659877e2e758f4ce405e1d3f8352b
Шаблон:Карточка/изображение/doc
10
222
492
2023-12-26T21:37:39Z
ruwiki>Q-bit array
0
[[ВП:Откат|откат]] правок [[Special:Contribs/178.67.199.169|178.67.199.169]] ([[UT:178.67.199.169|обс.]]) к версии DmitTrix
wikitext
text/x-wiki
{{docpage}}
{{high-use}}
Используется в [[Википедия:Шаблоны-карточки|шаблонах-карточках]] для вывода полей изображений, которые не нужно привязывать к Викиданным (в противном случае используется <code>{{tp|wikidata|P18|caption=<nowiki>{{{описание изображения|}}}</nowiki>|size=<nowiki>{{{ширина|}}}</nowiki>}}</code>).
== Заполнение в статьях ==
Для изображений в формате «'''<nowiki>[[Файл:<Имя>|…]]</nowiki>'''» (и вообще для любого параметра, начинающегося с «'''['''», «'''{'''» или «'''<'''») текст вставится без изменения:
<nowiki>{{{изображение|}}}</nowiki>
Если же просто указано название изображения, то оно оформится так:
<nowiki>[[Файл:{{{изображение|}}}|274x400px]]</nowiki>
== Использование шаблона ==
Вставляется в шаблон {{t|карточка}} — либо в поле {{para|изображение}}, либо в поле {{para|текстN}} (в таком случае может понадобиться сбросить паддинги: {{para|стиль_текстаN|padding:0;}}).
Формат применения:
<nowiki>| изображение = {{Карточка/изображение|{{{изображение|}}}|size={{{ширина|}}}|caption={{{описание изображения|}}}}}</nowiki>
== TemplateData ==
<templatedata>
{
"description": "Этот шаблон используется для вставки параметра изображения.",
"params": {
"1": {
"label": "1",
"description": "Изображение в любом виде, если '''none''' или '''нет''', то игнорируется.",
"type": "string",
"required": false
},
"caption": {
"label": "caption",
"description": "Подпись под изображением.",
"type": "string",
"required": false
},
"size": {
"aliases": [
"2"
],
"label": "size",
"description": "Его размер, можно с '''px''' или без, по-умолчанию — '''274x400px'''.",
"type": "string"
}
},
"paramOrder": [
"1",
"size",
"caption"
]
}
</templatedata>
== См. также ==
* [[Шаблон:Карточка/изображение/тесты]] (для проверки изменений)
* {{tl|URL}}
{{Подстраницы шаблона Карточка}}
<includeonly>
[[Категория:Шаблоны:Подстраницы шаблона Карточка|изображение]]
</includeonly>
1a53aa3106ad42492ac93048c8554950e40a1bf8
Шаблон:Учёное звание
10
295
751
2024-01-09T17:19:56Z
ruwiki>MBH
0
wikitext
text/x-wiki
<includeonly>{{#switch: {{{1|}}}
<!-- современная Россия -->
| РАН = {{#switch: {{{2|}}}| 1 = [[Члены-корреспонденты РАН|член-корреспондент РАН]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты РАН]]}}| 0 = [[Действительные члены РАН|академик РАН]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены РАН]]}}|<!--пустое значение-->}} <!-- Российская академия наук -->
| РАМН = {{#switch: {{{2|}}}| 1 = [[Члены-корреспонденты РАМН|член-корреспондент РАМН]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты РАМН]]}}| 0 = [[Российская академия медицинских наук|академик РАМН]]{{#if:{{NAMESPACE}}||[[Категория:Академики РАМН]]}}|<!--пустое значение-->}} <!-- Российская академия медицинских наук -->
| РАО = {{#switch: {{{2|}}}| 1 = [[Российская академия образования|член-корреспондент РАО]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты РАО]]}}| 0 = [[Действительные члены (академики) Российской академии образования|академик РАО]]{{#if:{{NAMESPACE}}||[[Категория:Академики РАО]]}}|<!--пустое значение-->}} <!-- Российская академия образования -->
| РАСХН = {{#switch: {{{2|}}}| 1 = [[Российская академия сельскохозяйственных наук|член-корреспондент РАСХН]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты РАСХН]]}}| 0 = [[Российская академия сельскохозяйственных наук|академик РАСХН]]{{#if:{{NAMESPACE}}||[[Категория:Академики РАСХН]]}}|<!--пустое значение-->}} <!-- Российская академия сельскохозяйственных наук -->
| РААСН = {{#switch: {{{2|}}}| 1 = [[Члены-корреспонденты Российской академии архитектуры и строительных наук|член-корреспондент РААСН]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты РААСН]]}}| 0 = [[Академики Российской академии архитектуры и строительных наук|академик РААСН]]{{#if:{{NAMESPACE}}||[[Категория:Академики РААСН]]}}|<!--пустое значение-->}} <!-- Российская академия архитектуры и строительных наук -->
| РАХ = {{#switch: {{{2|}}}| 1 = [[Российская академия художеств|член-корреспондент РАХ]]<br />{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты РАХ]]}}| 0 = [[Список действительных членов РАХ|академик РАХ]] {{#if:{{NAMESPACE}}||[[Категория:Действительные члены РАХ]]}}|<!--пустое значение-->}} <!-- Российская академия художеств -->
<!-- СССР -->
| АН СССР = {{#switch: {{{2|}}}| 1 = [[Члены-корреспонденты РАН за всю историю существования|член-корреспондент АН СССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН СССР]]}}| 0 = [[Академики АН СССР|академик АН СССР]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены АН СССР]]}}|<!--пустое значение-->}} <!-- Академия наук СССР -->
| АМН СССР = {{#switch: {{{2|}}}| 1 = [[Академия медицинских наук СССР|член-корреспондент АМН СССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АМН СССР]]}}| 0 = [[Академия медицинских наук СССР|академик АМН СССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АМН СССР]]}}|<!--пустое значение-->}} <!-- Академия медицинских наук СССР (1944—1992) -->
| АПН СССР = {{#switch: {{{2|}}}| 1 = [[Российская академия образования|член-корреспондент АПН СССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АПН СССР]]}}| 0 = [[Российская академия образования|академик АПН СССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АПН СССР]]}}|<!--пустое значение-->}} <!-- Академия педагогических наук СССР (1966—1992) -->
| ВАСХНИЛ = {{#switch: {{{2|}}}| 1 = [[Список членов-корреспондентов ВАСХНИЛ и РАСХН|член-корреспондент ВАСХНИЛ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты ВАСХНИЛ]]}}| 0 = [[Всесоюзная академия сельскохозяйственных наук имени Ленина|академик ВАСХНИЛ]]{{#if:{{NAMESPACE}}||[[Категория:Академики ВАСХНИЛ]]}}|<!--пустое значение-->}} <!-- ВАСХНИЛ (1929—1992) -->
| АА СССР = {{#switch: {{{2|}}}| 1 = [[Российская академия архитектуры и строительных наук|член-корреспондент АА СССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АА СССР]]}}| 0 = [[Российская академия архитектуры и строительных наук|академик АА СССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики Академии архитектуры СССР]]}}|<!--пустое значение-->}} <!-- Академия архитектуры СССР (1934—1956) и Академия строительства и архитектуры СССР (1956—1964) -->
| АХ СССР = {{#switch: {{{2|}}}| 1 = [[Академия художеств СССР|член-корреспондент АХ СССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Академии художеств СССР]]}}| 0 = [[Академия художеств СССР|академик АХ СССР]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены Академии художеств СССР]]}}|<!--пустое значение-->}} <!-- Академия художеств СССР республики ССР -->
| АН АзССР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Азербайджана|член-корреспондент АН Азербайджанской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Азербайджанской ССР]]}}| 0 = [[Национальная академия наук Азербайджана|академик АН Азербайджанской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Азербайджанской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Азербайджанской ССР -->
| АН АрмССР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Республики Армения|член-корреспондент АН Армянской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Армянской ССР]]}}| 0 = [[Действительные члены НАН Армении за всю историю существования|академик АН Армянской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Армянской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Армянской ССР -->
| АН БССР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Беларуси|член-корреспондент АН БССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Академии наук Белорусской ССР]]}}| 0 = [[Национальная академия наук Беларуси|академик АН БССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики Академии наук Белорусской ССР]]}}|<!--пустое значение-->}} <!-- Белорусская академия наук в 1928-1936 гг.; Академия наук Белорусской ССР в 1936-1991 гг. -->
| АН ГрузССР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Грузии|член-корреспондент АН Грузинской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Грузинской ССР]]}}| 0 = [[Национальная академия наук Грузии|академик АН Грузинской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Грузинской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Грузинской ССР -->
| АН МССР = {{#switch: {{{2|}}}| 1 = [[Академия наук Молдавии|член-корреспондент АН МССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Молдавской ССР]]}}| 0 = [[Академия наук Молдавии|академик АН МССР]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены Академии наук Молдавской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Молдавской ССР -->
| АН КазССР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Казахстана|член-корреспондент АН Казахской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Казахской ССР]]}}| 0 = [[Национальная академия наук Казахстана|академик АН Казахской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Казахской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Казахской ССР -->
| АН КиргССР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Кыргызской Республики|член-корреспондент АН Киргизской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Киргизской ССР]]}}| 0 = [[Национальная академия наук Кыргызской Республики|академик АН Киргизской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Киргизской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Киргизской ССР -->
| АН ЛатССР = {{#switch: {{{2|}}}| 1 = [[Академия наук Латвии|член-корреспондент АН Латвийской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Латвийской ССР]]}}| 0 = [[Академия наук Латвии|академик АН Латвийской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Латвийской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Латвийской ССР -->
| АН ЛитССР = {{#switch: {{{2|}}}| 1 = [[Академия наук Литвы|член-корреспондент АН Литовской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Литовской ССР]]}}| 0 = [[Академия наук Литвы|академик АН Литовской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Литовской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Литовской ССР -->
| АН УзССР = {{#switch: {{{2|}}}| 1 = [[Академия наук Узбекистана|член-корреспондент АН Узбекской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Узбекской ССР]]}}| 0 = [[Академия наук Узбекистана|академик АН Узбекской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Узбекской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Узбекской ССР -->
| АН УССР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Украины|член-корреспондент АН УССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН УССР]]}}| 0 = [[Национальная академия наук Украины|академик АН УССР]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены АН УССР]]}}|<!--пустое значение-->}}<!-- Академия наук Украинской ССР -->
| АН ЭССР = {{#switch: {{{2|}}}| 1 = [[Эстонская академия наук|член-корреспондент АН ЭССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Эстонской ССР]]}}| 0 = [[Эстонская академия наук|академик АН ЭССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Эстонской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Эстонской ССР -->
| АПН РСФСР = {{#switch: {{{2|}}}| 1 = [[Российская академия образования|член-корреспондент АПН РСФСР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АПН РСФСР]]}}| 0 = [[Российская академия образования|действительный член АПН РСФСР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АПН РСФСР]]}}|<!--пустое значение-->}} <!-- Академия педагогических наук РСФСР -->
| АН ТаджССР = {{#switch: {{{2|}}}| 1 = [[Академия наук Республики Таджикистан|член-корреспондент АН Таджикской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Таджикской ССР]]}}| 0 = [[Академия наук Республики Таджикистан|действительный член АН Таджикской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Таджикской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Таджикской ССР -->
| АН ТуркССР = {{#switch: {{{2|}}}| 1 = [[Академия наук Туркмении|член-корреспондент АН Туркменской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Туркменской ССР]]}}| 0 = [[Академия наук Туркмении|действительный член АН Туркменской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Туркменской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Туркменской ССР -->
<!-- постсоветские страны -->
| НАНБ | АНБ = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Беларуси|член-корреспондент НАНБ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Национальной академии наук Беларуси]]}}| 0 = [[Национальная академия наук Беларуси|академик НАНБ]]{{#if:{{NAMESPACE}}||[[Категория:Академики Национальной академии наук Беларуси]]}}|<!--пустое значение-->}} <!-- Академия наук Беларуси в 1991—1997 гг (АНБ); Национальная академия наук Беларуси (НАН Беларуси, или НАНБ) с 1997 -->
| АНМ = {{#switch: {{{2|}}}| 1 = [[Академия наук Молдавии|член-корреспондент АНМ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АНМ]]}}| 0 = [[Академия наук Молдавии|академик АНМ]]{{#if:{{NAMESPACE}}||[[Категория:Академики Молдовы]]}}|<!--пустое значение-->}}
| ААНБ = {{#switch: {{{2|}}}| 1 = [[Академия аграрных наук Беларуси|член-корреспондент ААНБ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты ААНБ]]}}| 0 = [[Академия аграрных наук Беларуси|академик ААНБ]]{{#if:{{NAMESPACE}}||[[Категория:Академики ААНБ]]}}|<!--пустое значение-->}} <!-- Академия аграрных наук Беларуси (ААН Беларуси) -->
| НАН РК = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Казахстана|член-корреспондент НАН РК]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты НАН Казахстана]]}}| 0 = [[Национальная академия наук Казахстана|академик НАН РК]]{{#if:{{NAMESPACE}}||[[Категория:Академики НАН Казахстана]]}}|<!--пустое значение-->}} <!-- Академия наук Казахстана -->
| НАН КР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Кыргызской Республики|член-корреспондент НАН КР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты НАН Кыргызстана]]}}| 0 = [[Национальная академия наук Кыргызской Республики|академик НАН КР]]{{#if:{{NAMESPACE}}||[[Категория:Академики НАН Кыргызстана]]}}|<!--пустое значение-->}} <!-- Академия наук Кыргызстана-->
| НАН РА = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Республики Армения|член-корреспондент НАН РА]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты НАН Армении]]}}| 0 = [[Действительные члены НАН Армении за всю историю существования|академик НАН РА]]{{#if:{{NAMESPACE}}||[[Категория:Академики НАН Армении]]}}|<!--пустое значение-->}} <!-- Национальная академия наук Армении -->
| НАНА = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Азербайджана|член-корреспондент НАНА]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты НАН Азербайджана]]}}| 0 = [[Национальная академия наук Азербайджана|академик НАНА]]{{#if:{{NAMESPACE}}||[[Категория:Академики НАН Азербайджана]]}}|<!--пустое значение-->}} <!-- Национальная академия наук Азербайджана -->
| НАНУ = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Украины|член-корреспондент НАНУ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты НАН Украины]]}}| 0 = [[Национальная академия наук Украины|академик НАНУ]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены НАН Украины]]}}|<!--пустое значение-->}} <!-- Национальная академия наук Украины -->
| НАМНУ = {{#switch: {{{2|}}}| 1 = [[Национальная академия медицинских наук Украины|член-корреспондент НАМНУ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Национальной академии медицинских наук Украины]]}}| 0 = [[Национальная академия медицинских наук Украины|академик НАМНУ]]{{#if:{{NAMESPACE}}||[[Категория:Академики Национальной академии медицинских наук Украины]]}}|<!--пустое значение-->}} <!-- Национальная академия медицинских наук Украины -->
| СПбАН = {{#switch: {{{2|}}}| 1 = [[Петербургская академия наук|член-корреспондент СПбАН]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Петербургской академии наук]]}}| 0 = [[Петербургская академия наук|академик СПбАН]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены Петербургской академии наук]]}}|<!--пустое значение-->}} <!-- Петербургская академия наук -->
| ПАН = {{#switch: {{{2|}}}| 1 = [[Польская академия наук|член-корреспондент ПАН]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Польской академии наук]]}}| 0 = [[Польская академия наук|действительный член ПАН]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены Польской академии наук]]}}| 2 = [[Польская академия наук|иностранный член ПАН]]{{#if:{{NAMESPACE}}||[[Категория:Иностранные члены Польской академии наук]]}}| 3 = [[Польская академия наук|сотрудник ПАН]]{{#if:{{NAMESPACE}}||[[Категория:Сотрудники Польской академии наук]]}}|<!--пустое значение-->}} <!-- Польская академия наук -->
| НАПНУ = {{#switch: {{{2|}}}| 1 = [[Национальная академия педагогических наук Украины|член-корреспондент НАПНУ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Национальной академии педагогических наук Украины]]}}| 0 = [[Национальная академия педагогических наук Украины|действительный член НАПНУ]]{{#if:{{NAMESPACE}}||[[Категория:Академики Национальной академии педагогических наук Украины]]}}|<!--пустое значение-->}} <!-- Национальная академия педагогических наук Украины -->
| НАПрНУ = {{#switch: {{{2|}}}| 1 = [[Национальная академия правовых наук Украины|член-корреспондент НАПрНУ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Национальной академии правовых наук Украины]]}}| 0 = [[Национальная академия правовых наук Украины|действительный член НАПрНУ]]{{#if:{{NAMESPACE}}||[[Категория:Академики Национальной академии правовых наук Украины]]}}|<!--пустое значение-->}} <!-- Национальная академия правовых наук Украины -->
| НАН Грузии = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Грузии|член-корреспондент НАН Грузии]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Академии наук Грузии]]}}| 0 = [[Национальная академия наук Грузии|действительный член НАН Грузии]]{{#if:{{NAMESPACE}}||[[Категория:Академики Академии наук Грузии]]}}|<!--пустое значение-->}} <!-- Национальная академия наук Грузии-->
| АН Узбекистана = {{#switch: {{{2|}}}| 1 = [[Академия наук Узбекистана|член-корреспондент АН Узбекистана]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Узбекистана]]}}| 0 = [[Академия наук Узбекистана|действительный член АН Узбекистана]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Узбекистана]]}}|<!--пустое значение-->}} <!-- Академия наук Узбекистана -->
<!-- Научное звание -->
| {{#switch: {{{2|}}}| 1 = [[доцент]]| доцент = [[доцент]]| 0 = [[профессор (звание)|профессор]] | профессор = [[профессор (звание)|профессор]] |<!--пустое значение-->}} <!-- не академики -->
}}</includeonly><noinclude>{{doc}}</noinclude>
c96f56648a68c3a7ea133f232c7bf1196d3fa462
Шаблон:Историческое государство
10
185
412
2024-02-12T11:22:03Z
ruwiki>Stjn
0
[[ВП:×|отмена]]: зачем? напишите ту же информацию в имеющемся поле население
wikitext
text/x-wiki
{{Карточка
|имя = Историческое государство
|from = {{{from|}}}
|стиль_тела = width:28em;
|стиль_заголовков =
|вверху0 = {{#if: {{{статус|}}} | {{{статус}}} | Историческое государство }}
|вверху = {{Карточка/название|{{{название|}}}|from={{{from|}}}}}
|вверху2 = {{Карточка/оригинал названия|{{{самоназвание|}}}|from={{{from|}}}}}
|текст1 = {{Карточка/флаг и герб
| флаг = {{{флаг|}}}
| флаг подпись = {{{описание_флага|}}}
| герб = {{{герб|}}}
| герб подпись = {{{описание_герба|}}}
|from={{{from|}}}}}
|текст2 = {{#if: {{{девиз|}}} | [[Девиз]]: ''«{{{девиз}}}»''{{#if: {{{перевод девиза|}}}|<br />''«{{{перевод девиза}}}»''}} }}
|текст3 = {{if-wikidata|p85|{{{гимн|}}}|[[Государственный гимн|Гимн]]: {{wikidata|p85|{{{гимн|}}}|from={{{from|}}}}}|from={{{from|}}}}}
|викиданные3 = p85
|текст4 = {{wikidata|p242[1]|{{{карта|}}}|size={{{размер|}}}|caption={{{описание|}}}|from={{{from|}}}}}
|заголовок5 = <div style="float:left; margin-right:0.5em; text-align:left; width:4em;"><!--
-->{{#if:{{{p8|}}}{{{successionbelow|}}}|[[#before-after|↓]]|<!--
-->{{#if:{{{p1|}}}|{{nobr|[[{{{p1}}}|←]] {{#if:{{{flag_p1|}}}|[[Файл:{{{flag_p1|}}}|border|30px|link={{{p1|}}}]]|{{#if:{{{image_p1|}}}|{{{image_p1}}}|[[Файл:Flag of None.svg|30px|border]]}}}}}}}}<!--
-->{{#if:{{{p2|}}}|<br>{{nobr|[[{{{p2}}}|←]] {{#if:{{{flag_p2|}}}|[[Файл:{{{flag_p2}}}|border|30px|link={{{p2|}}}]]|{{#if:{{{image_p2|}}}|{{{image_p2}}}|[[Файл:Flag of None.svg|30px|border]]}}}}}}}}<!--
-->{{#if:{{{p3|}}}|<br>{{nobr|[[{{{p3}}}|←]] {{#if:{{{flag_p3|}}}|[[Файл:{{{flag_p3}}}|border|30px|link={{{p3|}}}]]|{{#if:{{{image_p3|}}}|{{{image_p3}}}|[[Файл:Flag of None.svg|30px|border]]}}}}}}}}<!--
-->{{#if:{{{p4|}}}|<br>{{nobr|[[{{{p4}}}|←]] {{#if:{{{flag_p4|}}}|[[Файл:{{{flag_p4}}}|border|30px|link={{{p4|}}}]]|{{#if:{{{image_p4|}}}|{{{image_p4}}}|[[Файл:Flag of None.svg|30px|border]]}}}}}}}}<!--
-->{{#if:{{{p5|}}}|<br>{{nobr|[[{{{p5}}}|←]] {{#if:{{{flag_p5|}}}|[[Файл:{{{flag_p5}}}|border|30px|link={{{p5|}}}]]|{{#if:{{{image_p5|}}}|{{{image_p5}}}|[[Файл:Flag of None.svg|30px|border]]}}}}}}}}<!--
-->{{#if:{{{p6|}}}|<br>{{nobr|[[{{{p6}}}|←]] {{#if:{{{flag_p6|}}}|[[Файл:{{{flag_p6}}}|border|30px|link={{{p6|}}}]]|{{#if:{{{image_p6|}}}|{{{image_p6}}}|[[Файл:Flag of None.svg|30px|border]]}}}}}}}}<!--
-->{{#if:{{{p7|}}}|<br>{{nobr|[[{{{p7}}}|←]] {{#if:{{{flag_p7|}}}|[[Файл:{{{flag_p7}}}|border|30px|link={{{p7|}}}]]|{{#if:{{{image_p7|}}}|{{{image_p7}}}|[[Файл:Flag of None.svg|30px|border]]}}}}}}}}}}<!--
--></div>
<div style="float:right; margin-left:0.5em; text-align:right; width:4em;"><!--
-->{{#if:{{{s8|}}}{{{successionbelow|}}}|[[#before-after|↓]]|<!--
-->{{#if:{{{s1|}}}|{{nobr|{{#if:{{{flag_s1|}}}|[[Файл:{{{flag_s1}}}|border|30px|link={{{s1|}}}]]|{{#if:{{{image_s1|}}}|{{{image_s1}}}|[[Файл:Flag of None.svg|30px|border]]}}}} [[{{{s1}}}|→]]}}}}<!--
-->{{#if:{{{s2|}}}|<br>{{nobr|{{#if:{{{flag_s2|}}}|[[Файл:{{{flag_s2}}}|border|30px|link={{{s2|}}}]]|{{#if:{{{image_s2|}}}|{{{image_s2}}}|[[Файл:Flag of None.svg|30px|border]]}}}} [[{{{s2}}}|→]]}}}}<!--
-->{{#if:{{{s3|}}}|<br>{{nobr|{{#if:{{{flag_s3|}}}|[[Файл:{{{flag_s3}}}|border|30px|link={{{s3|}}}]]|{{#if:{{{image_s3|}}}|{{{image_s3}}}|[[Файл:Flag of None.svg|30px|border]]}}}} [[{{{s3}}}|→]]}}}}<!--
-->{{#if:{{{s4|}}}|<br>{{nobr|{{#if:{{{flag_s4|}}}|[[Файл:{{{flag_s4}}}|border|30px|link={{{s4|}}}]]|{{#if:{{{image_s4|}}}|{{{image_s4}}}|[[Файл:Flag of None.svg|30px|border]]}}}} [[{{{s4}}}|→]]}}}}<!--
-->{{#if:{{{s5|}}}|<br>{{nobr|{{#if:{{{flag_s5|}}}|[[Файл:{{{flag_s5}}}|border|30px|link={{{s5|}}}]]|{{#if:{{{image_s5|}}}|{{{image_s5}}}|[[Файл:Flag of None.svg|30px|border]]}}}} [[{{{s5}}}|→]]}}}}<!--
-->{{#if:{{{s6|}}}|<br>{{nobr|{{#if:{{{flag_s6|}}}|[[Файл:{{{flag_s6}}}|border|30px|link={{{s6|}}}]]|{{#if:{{{image_s6|}}}|{{{image_s6}}}|[[Файл:Flag of None.svg|30px|border]]}}}} [[{{{s6}}}|→]]}}}}<!--
-->{{#if:{{{s7|}}}|<br>{{nobr|{{#if:{{{flag_s7|}}}|[[Файл:{{{flag_s7}}}|border|30px|link={{{s7|}}}]]|{{#if:{{{image_s7|}}}|{{{image_s7}}}|[[Файл:Flag of None.svg|30px|border]]}}}} [[{{{s7}}}|→]]}}}}}}<!--
--></div>
{{#if: {{wikidata|p571|{{{образовано|}}}|plain=true|from={{{from|}}}}} {{wikidata|p576|{{{ликвидировано|}}}|plain=true|from={{{from|}}}}} | <div style="margin:0 4em;">{{nobr|{{wikidata|p571|{{{образовано|}}}|from={{{from|}}}}} —}} {{nobr|{{wikidata|p576|{{{ликвидировано|}}}|from={{{from|}}}}}}}</div> }}
{{-}}
|метка6 = [[Столица]]
|текст6 = {{{столица|}}}
|викиданные6 = p36
|метка7 = Крупнейшие города
|текст7 = {{{города|}}}
|викиданные7 =
|метка8 = Язык(и)
|текст8 = {{{язык|}}}
|викиданные8 = p2936
|метка9 = [[Официальный язык]]
|текст9 = {{{официальный язык|}}}
|викиданные9 = p37
|метка10 = [[Религия]]
|текст10 = {{{религия|}}}
|викиданные10 = p3075
|метка11 = Денежная единица
|текст11 = {{{валюта|}}}
|викиданные11 = p38
|метка12 = Площадь
|текст12 = {{{площадь|}}}
|викиданные12 = p2046
|метка13 = Население
|текст13 = {{{население|}}}
|викиданные13 = p1082
|метка14 = Форма правления
|текст14 = {{{форма_правления|}}}
|викиданные14 = p122
|метка15 = Династия
|текст15 = {{{династия|}}}
|викиданные15 =
|метка16 = {{{дополнительный_параметр}}}
|текст16 = {{{содержимое_параметра|}}}
|викиданные16 =
|метка17 = {{{дополнительный_параметр1}}}
|текст17 = {{{содержимое_параметра1|}}}
|викиданные17 =
|метка18 = {{{дополнительный_параметр2}}}
|текст18 = {{{содержимое_параметра2|}}}
|викиданные18 =
|метка19 = {{{дополнительный_параметр3}}}
|текст19 = {{{содержимое_параметра3|}}}
|викиданные19 =
|метка20 = {{{дополнительный_параметр4}}}
|текст20 = {{{содержимое_параметра4|}}}
|викиданные20 =
|метка21 = {{{дополнительный_параметр5}}}
|текст21 = {{{содержимое_параметра5|}}}
|викиданные21 =
|метка22 = {{{дополнительный_параметр6}}}
|текст22 = {{{содержимое_параметра6|}}}
|викиданные22 =
|заголовок23 = {{#if: {{{титул_правителей2|}}}{{{титул_правителей3|}}}{{{титул_правителей4|}}}{{{титул_правителей5|}}}{{{титул_правителей6|}}}{{{титул_правителей7|}}}{{{титул_правителей8|}}}{{{титул_правителей9|}}}{{{титул_правителей10|}}}{{{титул_правителей11|}}}{{{титул_правителей12|}}}{{{титул_правителей13|}}}{{{титул_правителей14|}}}{{{титул_правителей15|}}}{{{титул_правителей16|}}} | Главы государства }}
|заголовок24 = {{#if: {{{правитель1|}}} | {{{титул_правителя1|{{{титул_правителей}}}}}} }}
|стиль_заголовка24 = {{#if: {{{титул_правителей2|}}}{{{титул_правителей3|}}}{{{титул_правителей4|}}}{{{титул_правителей5|}}}{{{титул_правителей6|}}}{{{титул_правителей7|}}}{{{титул_правителей8|}}}{{{титул_правителей9|}}}{{{титул_правителей10|}}}{{{титул_правителей11|}}}{{{титул_правителей12|}}}{{{титул_правителей13|}}}{{{титул_правителей14|}}}{{{титул_правителей15|}}}{{{титул_правителей16|}}} | background: transparent; padding-bottom:0; border-bottom:0; text-align:left; }}
|метка25 = • {{{год_правителя1}}}
|стиль_метки25 = font-weight:normal; {{#if: {{{титул_правителей2|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст25 = {{{правитель1|}}}
|стиль_текста25 = {{#if: {{{титул_правителей2|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные25 =
|заголовок26 = {{{титул_правителей2|}}}
|стиль_заголовка26 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left;
|метка27 = • {{{год_правителя2}}}
|стиль_метки27 = font-weight:normal; {{#if: {{{титул_правителей3|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст27 = {{{правитель2|}}}
|стиль_текста27 = {{#if: {{{титул_правителей3|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные27 =
|заголовок28 = {{{титул_правителей3|}}}
|стиль_заголовка28 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left;
|метка29 = • {{{год_правителя3}}}
|стиль_метки29 = font-weight:normal; {{#if: {{{титул_правителей4|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст29 = {{{правитель3|}}}
|стиль_текста29 = {{#if: {{{титул_правителей4|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные29 =
|заголовок30 = {{{титул_правителей4|}}}
|стиль_заголовка30 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left;
|метка31 = • {{{год_правителя4}}}
|стиль_метки31 = font-weight:normal; {{#if: {{{титул_правителей5|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст31 = {{{правитель4|}}}
|стиль_текста31 = {{#if: {{{титул_правителей5|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные31 =
|заголовок32 = {{{титул_правителей5|}}}
|стиль_заголовка32 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left;
|метка33 = • {{{год_правителя5}}}
|стиль_метки33 = font-weight:normal; {{#if: {{{титул_правителей6|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст33 = {{{правитель5|}}}
|стиль_текста33 = {{#if: {{{титул_правителей6|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные33 =
|заголовок34 = {{{титул_правителей6|}}}
|стиль_заголовка34 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left;
|метка35 = • {{{год_правителя6}}}
|стиль_метки35 = font-weight:normal; {{#if: {{{титул_правителей7|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст35 = {{{правитель6|}}}
|стиль_текста35 = {{#if: {{{титул_правителей7|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные35 =
|заголовок36 = {{{титул_правителей7|}}}
|стиль_заголовка36 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left;
|метка37 = • {{{год_правителя7}}}
|стиль_метки37 = font-weight:normal; {{#if: {{{титул_правителей8|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст37 = {{{правитель7|}}}
|стиль_текста37 = {{#if: {{{титул_правителей8|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные37 =
|заголовок38 = {{{титул_правителей8|}}}
|стиль_заголовка38 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left;
|метка39 = • {{{год_правителя8}}}
|стиль_метки39 = font-weight:normal; {{#if: {{{титул_правителей9|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст39 = {{{правитель8|}}}
|стиль_текста39 = {{#if: {{{титул_правителей9|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные39 =
|заголовок40 = {{{титул_правителей9|}}}
|стиль_заголовка40 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left;
|метка41 = • {{{год_правителя9}}}
|стиль_метки41 = font-weight:normal; {{#if: {{{титул_правителей10|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст41 = {{{правитель9|}}}
|стиль_текста41 = {{#if: {{{титул_правителей10|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные41 =
|заголовок42 = {{{титул_правителей10|}}}
|стиль_заголовка42 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left;
|метка43 = • {{{год_правителя10}}}
|стиль_метки43 = font-weight:normal; {{#if: {{{титул_правителей11|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст43 = {{{правитель10|}}}
|стиль_текста43 = {{#if: {{{титул_правителей11|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные43 =
|заголовок44 = {{{титул_правителей11|}}}
|стиль_заголовка44 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left;
|метка45 = • {{{год_правителя11}}}
|стиль_метки45 = font-weight:normal; {{#if: {{{титул_правителей12|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст45 = {{{правитель11|}}}
|стиль_текста45 = {{#if: {{{титул_правителей12|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные45 =
|заголовок46 = {{{титул_правителей12|}}}
|стиль_заголовка46 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left;
|метка47 = • {{{год_правителя12}}}
|стиль_метки47 = font-weight:normal; {{#if: {{{титул_правителей13|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст47 = {{{правитель12|}}}
|стиль_текста47 = {{#if: {{{титул_правителей13|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные47 =
|заголовок48 = {{{титул_правителей13|}}}
|стиль_заголовка48 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left;
|метка49 = • {{{год_правителя13}}}
|стиль_метки49 = font-weight:normal; {{#if: {{{титул_правителей14|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст49 = {{{правитель13|}}}
|стиль_текста49 = {{#if: {{{титул_правителей14|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные49 =
|заголовок50 = {{{титул_правителей14|}}}
|стиль_заголовка50 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left;
|метка51 = • {{{год_правителя14}}}
|стиль_метки51 = font-weight:normal; {{#if: {{{титул_правителей15|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст51 = {{{правитель14|}}}
|стиль_текста51 = {{#if: {{{титул_правителей15|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные51 =
|заголовок52 = {{{титул_правителей15|}}}
|стиль_заголовка52 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left;
|метка53 = • {{{год_правителя15}}}
|стиль_метки53 = font-weight:normal; {{#if: {{{титул_правителей16|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст53 = {{{правитель15|}}}
|стиль_текста53 = {{#if: {{{титул_правителей16|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные53 =
|заголовок54 = {{{титул_правителей16|}}}
|стиль_заголовка54 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left;
|метка55 = • {{{год_правителя16}}}
|стиль_метки55 = font-weight:normal; padding-top:0; border-top:0;
|текст55 = {{{правитель16|}}}
|стиль_текста55 = padding-top:0; border-top:0;
|викиданные55 =
|заголовок56 = {{#if: {{{Этап1|}}} | История }}
|метка57 = • {{nobr|{{{Дата1|}}}{{#if: {{{Дата1|}}} | {{sp}} }}{{{Год1|}}}}}
|стиль_метки57 = font-weight:normal; {{#if: {{{Этап2|}}} | padding-bottom:0; border-bottom:0;}}
|текст57 = {{{Этап1|}}}
|стиль_текста57 = {{#if: {{{Этап2|}}} | padding-bottom:0; border-bottom:0;}}
|викиданные57 =
|метка58 = • {{nobr|{{{Дата2|}}}{{#if: {{{Дата2|}}} | {{sp}} }}{{{Год2|}}}}}
|стиль_метки58 = font-weight:normal; {{#if: {{{Этап3|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст58 = {{{Этап2|}}}
|стиль_текста58 = {{#if: {{{Этап3|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные58 =
|метка59 = • {{nobr|{{{Дата3|}}}{{#if: {{{Дата3|}}} | {{sp}} }}{{{Год3|}}}}}
|стиль_метки59 = font-weight:normal; {{#if: {{{Этап4|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст59 = {{{Этап3|}}}
|стиль_текста59 = {{#if: {{{Этап4|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные59 =
|метка60 = • {{nobr|{{{Дата4|}}}{{#if: {{{Дата4|}}} | {{sp}} }}{{{Год4|}}}}}
|стиль_метки60 = font-weight:normal; {{#if: {{{Этап5|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст60 = {{{Этап4|}}}
|стиль_текста60 = {{#if: {{{Этап5|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные60 =
|метка61 = • {{nobr|{{{Дата5|}}}{{#if: {{{Дата5|}}} | {{sp}} }}{{{Год5|}}}}}
|стиль_метки61 = font-weight:normal; {{#if: {{{Этап6|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст61 = {{{Этап5|}}}
|стиль_текста61 = {{#if: {{{Этап6|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные61 =
|метка62 = • {{nobr|{{{Дата6|}}}{{#if: {{{Дата6|}}} | {{sp}} }}{{{Год6|}}}}}
|стиль_метки62 = font-weight:normal; {{#if: {{{Этап7|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст62 = {{{Этап6|}}}
|стиль_текста62 = {{#if: {{{Этап7|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные62 =
|метка63 = • {{nobr|{{{Дата7|}}}{{#if: {{{Дата7|}}} | {{sp}} }}{{{Год7|}}}}}
|стиль_метки63 = font-weight:normal; {{#if: {{{Этап8|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст63 = {{{Этап7|}}}
|стиль_текста63 = {{#if: {{{Этап8|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные63 =
|метка64 = • {{nobr|{{{Дата8|}}}{{#if: {{{Дата8|}}} | {{sp}} }}{{{Год8|}}}}}
|стиль_метки64 = font-weight:normal; {{#if: {{{Этап9|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст64 = {{{Этап8|}}}
|стиль_текста64 = {{#if: {{{Этап9|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные64 =
|метка65 = • {{nobr|{{{Дата9|}}}{{#if: {{{Дата9|}}} | {{sp}} }}{{{Год9|}}}}}
|стиль_метки65 = font-weight:normal; {{#if: {{{Этап10|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст65 = {{{Этап9|}}}
|стиль_текста65 = {{#if: {{{Этап10|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные65 =
|метка66 = • {{nobr|{{{Дата10|}}}{{#if: {{{Дата10|}}} | {{sp}} }}{{{Год10|}}}}}
|стиль_метки66 = font-weight:normal; {{#if: {{{Этап11|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст66 = {{{Этап10|}}}
|стиль_текста66 = {{#if: {{{Этап11|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные66 =
|метка67 = • {{nobr|{{{Дата11|}}}{{#if: {{{Дата11|}}} | {{sp}} }}{{{Год11|}}}}}
|стиль_метки67 = font-weight:normal; padding-top:0; border-top:0;
|текст67 = {{{Этап11|}}}
|стиль_текста67 = padding-top:0; border-top:0;
|викиданные67 =
|заголовок68 = {{#if: {{{до|}}}{{{после|}}} | Преемственность }}
|текст69 = {{#if: {{{до|}}} | ← [[{{{до}}}]]
{{#if: {{{д1|}}} | ← [[{{{д1}}}]] }}
{{#if: {{{д2|}}} | ← [[{{{д2}}}]] }}
{{#if: {{{д3|}}} | ← [[{{{д3}}}]] }}
{{#if: {{{д4|}}} | ← [[{{{д4}}}]] }}
{{#if: {{{д5|}}} | ← [[{{{д5}}}]] }}
{{#if: {{{д6|}}} | ← [[{{{д6}}}]] }}
{{#if: {{{д7|}}} | ← [[{{{д7}}}]] }}
}}
|стиль_текста69 = text-align:left;
|текст70 = {{#if: {{{после|}}} | [[{{{после}}}]] →
{{#if: {{{п1|}}} | [[{{{п1}}}]] → }}
{{#if: {{{п2|}}} | [[{{{п2}}}]] → }}
{{#if: {{{п3|}}} | [[{{{п3}}}]] → }}
{{#if: {{{п4|}}} | [[{{{п4}}}]] → }}
{{#if: {{{п5|}}} | [[{{{п5}}}]] → }}
{{#if: {{{п6|}}} | [[{{{п6}}}]] → }}
{{#if: {{{п7|}}} | [[{{{п7}}}]] → }}
}}
|стиль_текста70 = text-align:right;
|заголовок71 = {{#ifeq: {{#expr: {{#expr:{{#if:{{{p8|}}}|1|0}}+{{#if:{{{s8|}}}|1|0}}}}+{{#if:{{{successionbelow|}}}|1|0}} > 0}} | 1 | {{Видимый якорь|before-after|текст=Предшественники и преемники}} }}
|текст72 = {{#ifeq: {{#expr: {{#expr:{{#if:{{{p8|}}}|1|0}}+{{#if:{{{s8|}}}|1|0}}}}+{{#if:{{{successionbelow|}}}|1|0}} > 0}} | 1 | <table style="display:table; margin:0; padding:0; table-layout:fixed; width:100%;">
<tr>
<td style="padding-left:0;">{{#if: {{{p1|}}}{{{successionbelow|}}} |
{{#if: {{{type_before|}}}{{{type_after|}}} | '''{{{type_before|Предшественники}}}''' }}
* {{#if:{{{flag_p1|}}}|[[Файл:{{{flag_p1}}}|20px|border]]|{{#if:{{{image_p1|}}}|{{{image_p1}}}}}}} [[{{{p1}}}]]<!--
-->{{#if: {{{p2|}}} | * {{#if:{{{flag_p2|}}}|[[Файл:{{{flag_p2}}}|20px|border]]|{{#if:{{{image_p2|}}}|{{{image_p2}}}}}}} [[{{{p2}}}]] }}<!--
-->{{#if: {{{p3|}}} | * {{#if:{{{flag_p3|}}}|[[Файл:{{{flag_p3}}}|20px|border]]|{{#if:{{{image_p3|}}}|{{{image_p3}}}}}}} [[{{{p3}}}]] }}<!--
-->{{#if: {{{p4|}}} | * {{#if:{{{flag_p4|}}}|[[Файл:{{{flag_p4}}}|20px|border]]|{{#if:{{{image_p4|}}}|{{{image_p4}}}}}}} [[{{{p4}}}]] }}<!--
-->{{#if: {{{p5|}}} | * {{#if:{{{flag_p5|}}}|[[Файл:{{{flag_p5}}}|20px|border]]|{{#if:{{{image_p5|}}}|{{{image_p5}}}}}}} [[{{{p5}}}]] }}<!--
-->{{#if: {{{p6|}}} | * {{#if:{{{flag_p6|}}}|[[Файл:{{{flag_p6}}}|20px|border]]|{{#if:{{{image_p6|}}}|{{{image_p6}}}}}}} [[{{{p6}}}]] }}<!--
-->{{#if: {{{p7|}}} | * {{#if:{{{flag_p7|}}}|[[Файл:{{{flag_p7}}}|20px|border]]|{{#if:{{{image_p7|}}}|{{{image_p7}}}}}}} [[{{{p7}}}]] }}<!--
-->{{#if: {{{p8|}}} | * {{#if:{{{flag_p8|}}}|[[Файл:{{{flag_p8}}}|20px|border]]|{{#if:{{{image_p8|}}}|{{{image_p8}}}}}}} [[{{{p8}}}]] }}<!--
-->{{#if: {{{p9|}}} | * {{#if:{{{flag_p9|}}}|[[Файл:{{{flag_p9}}}|20px|border]]|{{#if:{{{image_p9|}}}|{{{image_p9}}}}}}} [[{{{p9}}}]] }}<!--
-->{{#if: {{{p10|}}} | * {{#if:{{{flag_p10|}}}|[[Файл:{{{flag_p10}}}|20px|border]]|{{#if:{{{image_p10|}}}|{{{image_p10}}}}}}} [[{{{p10}}}]] }}<!--
-->{{#if: {{{p11|}}} | * {{#if:{{{flag_p11|}}}|[[Файл:{{{flag_p11}}}|20px|border]]|{{#if:{{{image_p11|}}}|{{{image_p11}}}}}}} [[{{{p11}}}]] }}<!--
-->{{#if: {{{p12|}}} | * {{#if:{{{flag_p12|}}}|[[Файл:{{{flag_p12}}}|20px|border]]|{{#if:{{{image_p12|}}}|{{{image_p12}}}}}}} [[{{{p12}}}]] }}<!--
-->{{#if: {{{p13|}}} | * {{#if:{{{flag_p13|}}}|[[Файл:{{{flag_p13}}}|20px|border]]|{{#if:{{{image_p13|}}}|{{{image_p13}}}}}}} [[{{{p13}}}]] }}<!--
-->{{#if: {{{p14|}}} | * {{#if:{{{flag_p14|}}}|[[Файл:{{{flag_p14}}}|20px|border]]|{{#if:{{{image_p14|}}}|{{{image_p14}}}}}}} [[{{{p14}}}]] }}<!--
-->{{#if: {{{p15|}}} | * {{#if:{{{flag_p15|}}}|[[Файл:{{{flag_p15}}}|20px|border]]|{{#if:{{{image_p15|}}}|{{{image_p15}}}}}}} [[{{{p15}}}]] }}
}}</td>
<td style="padding-right:0;">{{#if: {{{s1|}}}{{{successionbelow|}}} |
{{#if: {{{type_before|}}}{{{type_after|}}} | '''{{{type_after|Преемники}}}''' }}
* {{#if:{{{flag_s1|}}}|[[Файл:{{{flag_s1}}}|20px|border]]|{{#if:{{{image_s1|}}}|{{{image_s1}}}}}}} [[{{{s1}}}]]<!--
-->{{#if: {{{s2|}}} | * {{#if:{{{flag_s2|}}}|[[Файл:{{{flag_s2}}}|20px|border]]|{{#if:{{{image_s2|}}}|{{{image_s2}}}}}}} [[{{{s2}}}]] }}<!--
-->{{#if: {{{s3|}}} | * {{#if:{{{flag_s3|}}}|[[Файл:{{{flag_s3}}}|20px|border]]|{{#if:{{{image_s3|}}}|{{{image_s3}}}}}}} [[{{{s3}}}]] }}<!--
-->{{#if: {{{s4|}}} | * {{#if:{{{flag_s4|}}}|[[Файл:{{{flag_s4}}}|20px|border]]|{{#if:{{{image_s4|}}}|{{{image_s4}}}}}}} [[{{{s4}}}]] }}<!--
-->{{#if: {{{s5|}}} | * {{#if:{{{flag_s5|}}}|[[Файл:{{{flag_s5}}}|20px|border]]|{{#if:{{{image_s5|}}}|{{{image_s5}}}}}}} [[{{{s5}}}]] }}<!--
-->{{#if: {{{s6|}}} | * {{#if:{{{flag_s6|}}}|[[Файл:{{{flag_s6}}}|20px|border]]|{{#if:{{{image_s6|}}}|{{{image_s6}}}}}}} [[{{{s6}}}]] }}<!--
-->{{#if: {{{s7|}}} | * {{#if:{{{flag_s7|}}}|[[Файл:{{{flag_s7}}}|20px|border]]|{{#if:{{{image_s7|}}}|{{{image_s7}}}}}}} [[{{{s7}}}]] }}<!--
-->{{#if: {{{s8|}}} | * {{#if:{{{flag_s8|}}}|[[Файл:{{{flag_s8}}}|20px|border]]|{{#if:{{{image_s8|}}}|{{{image_s8}}}}}}} [[{{{s8}}}]] }}<!--
-->{{#if: {{{s9|}}} | * {{#if:{{{flag_s9|}}}|[[Файл:{{{flag_s9}}}|20px|border]]|{{#if:{{{image_s9|}}}|{{{image_s9}}}}}}} [[{{{s9}}}]] }}<!--
-->{{#if: {{{s10|}}} | * {{#if:{{{flag_s10|}}}|[[Файл:{{{flag_s10}}}|20px|border]]|{{#if:{{{image_s10|}}}|{{{image_s10}}}}}}} [[{{{s10}}}]] }}<!--
-->{{#if: {{{s11|}}} | * {{#if:{{{flag_s11|}}}|[[Файл:{{{flag_s11}}}|20px|border]]|{{#if:{{{image_s11|}}}|{{{image_s11}}}}}}} [[{{{s11}}}]] }}<!--
-->{{#if: {{{s12|}}} | * {{#if:{{{flag_s12|}}}|[[Файл:{{{flag_s12}}}|20px|border]]|{{#if:{{{image_s12|}}}|{{{image_s12}}}}}}} [[{{{s12}}}]] }}<!--
-->{{#if: {{{s13|}}} | * {{#if:{{{flag_s13|}}}|[[Файл:{{{flag_s13}}}|20px|border]]|{{#if:{{{image_s13|}}}|{{{image_s13}}}}}}} [[{{{s13}}}]] }}<!--
-->{{#if: {{{s14|}}} | * {{#if:{{{flag_s14|}}}|[[Файл:{{{flag_s14}}}|20px|border]]|{{#if:{{{image_s14|}}}|{{{image_s14}}}}}}} [[{{{s14}}}]] }}<!--
-->{{#if: {{{s15|}}} | * {{#if:{{{flag_s15|}}}|[[Файл:{{{flag_s15}}}|20px|border]]|{{#if:{{{image_s15|}}}|{{{image_s15}}}}}}} [[{{{s15}}}]] }}
}}</td>
</tr>
</table> }}
|стиль_текста72 = text-align:left;
|текст73 = {{{прим|}}}
|стиль_текста73 = border-top:1px solid #a2a9b1; color:#54595d; padding-top:0.5em; text-align:left;
|внизу = {{карточка/Викисклад|{{{викисклад|}}}|from={{{from|}}}}}
}}{{#if:{{NAMESPACE}}{{{nocat|}}}||<!--
-->{{категория по дате|{{{образовано|}}}|Государства и территории, основанные|p571|from={{{from|}}}}}<!--
-->{{категория по дате|{{{образовано2|}}}|Государства и территории, основанные|from={{{from|}}}}}<!--
-->{{категория по дате|{{{образовано3|}}}|Государства и территории, основанные|from={{{from|}}}}}<!--
-->{{категория по дате|{{{ликвидировано|}}}|Государства и территории, исчезнувшие|p576|from={{{from|}}}}}<!--
-->{{категория по дате|{{{ликвидировано2|}}}|Государства и территории, исчезнувшие|from={{{from|}}}}}<!--
-->{{категория по дате|{{{ликвидировано3|}}}|Государства и территории, исчезнувшие|from={{{from|}}}}}<!--
-->{{#ifeq:{{{флаг}}}|novalue|{{#if:{{wikidata|p41|from={{{from|}}}}}|[[Категория:Статьи со спорным параметром в Викиданных]]}}|}}{{#ifeq:{{{герб}}}|novalue|{{#if:{{if-wikidata|p94|from={{{from|}}}}}|[[Категория:Статьи со спорным параметром в Викиданных]]}}|}}<!--
-->}}<noinclude>{{doc}}</noinclude>
3f810e404f545118ca6d15a13a0a04829c1f3c88
Шаблон:Историческое государство/doc
10
191
428
2024-02-12T11:22:28Z
ruwiki>Stjn
0
[[ВП:×|отмена]]: зачем? напишите ту же информацию в имеющемся поле население
wikitext
text/x-wiki
{{docpage}}
{{Переписать шаблон|меташаблон=Карточка/блок с маркерами}}
Этот [[Википедия:Шаблоны-карточки|шаблон-карточка]] используется для вставки карточки в статьи об отдельных исторических государствах.
* для современных государств используется {{t|государство}}.
* для составных частей государств используется {{t|административная единица}}.
== Заготовка, включающая все возможные параметры ==
<pre>
{{Историческое государство
|название =
|самоназвание =
|статус =
|гимн =
|флаг =
|описание_флага =
|герб =
|описание_герба =
|карта =
|размер =
|описание =
<!-- |type_before = если этот параметр присутствует в шаблоне,
то необходимо указать примерно следующее: «Государства-основатели»,
иначе удалите его, автоматически будет указано: «Предшественники».-->
|p1 =
|flag_p1 =
|image_p1 =
|p2 =
|flag_p2 =
|image_p2 =
|p3 =
|flag_p3 =
|image_p3 =
|p4 =
|flag_p4 =
|image_p4 =
|образовано =
|ликвидировано =
<!-- |type_after = если этот параметр присутствует в шаблоне,
то необходимо указать примерно следующее: «Государства после распада…»,
иначе удалите его, автоматически будет указано: «Преемники».-->
|s1 =
|flag_s1 =
|image_s1 =
|s2 =
|flag_s2 =
|image_s2 =
|s3 =
|flag_s3 =
|image_s3 =
|s4 =
|flag_s4 =
|image_s4 =
|девиз =
|столица =
|города =
|язык =
|валюта =
|дополнительный_параметр =
|содержимое_параметра =
|площадь =
|население =
|форма_правления =
|династия =
|титул_правителей =
|правитель1 = <!--Не вставляйте в шаблон всех правителей, если их много — он не для этого! Создайте соответствующий раздел в статье. -->
|год_правителя1 =
|титул_правителей2 = <!--используется при изменении титула последующего правителя-->
|правитель2 =
|год_правителя2 =
|титул_правителей3 =
|правитель3 =
|год_правителя3 =
|титул_правителей4 =
|правитель4 =
|год_правителя4 =
|титул_правителей5 =
|правитель5 =
|год_правителя5 =
|титул_правителей6 =
|правитель6 =
|год_правителя6 =
|религия =
|дополнительный_параметр1 =
|содержимое_параметра1 =
|Этап1 =
|Дата1 =
|Год1 =
|Этап2 =
|Дата2 =
|Год2 =
|Этап3 =
|Дата3 =
|Год3 =
|Этап4 =
|Дата4 =
|Год4 =
|Этап5 =
|Дата5 =
|Год5 =
|Этап6 =
|Дата6 =
|Год6 =
|Этап7 =
|Дата7 =
|Год7 =
|Этап8 =
|Дата8 =
|Год8 =
|Этап9 =
|Дата9 =
|Год9 =
|Этап10 =
|Дата10 =
|Год10 =
|Этап11 =
|Дата11 =
|Год11 =
|дополнительный_параметр2 =
|содержимое_параметра2 =
|до =
|д1 =
|д2 =
|д3 =
|д4 =
|д5 =
|д6 =
|д7 =
|после =
|п1 =
|п2 =
|п3 =
|п4 =
|п5 =
|п6 =
|п7 =
|прим =
|викисклад =
}}
</pre>
* ''Название'' — официальное наименование административной единицы (если административная единица имела несколько официальных наименований — указывается то, что применялось на протяжении наибольшего времени существования территории).
* ''Самоназвание'' — название на официальном языке административной единицы.
* ''Статус'' — административный статус единицы (царство, княжество, королевство и т. д.).
* ''Гимн'' — гимн территории. Параметр поддерживает импорт викиданных.
* ''Флаг'' — флаг территории. Параметр поддерживает импорт викиданных. Есть возможность [[ВП:ЛЖЕГЕРБ|выключить]], заполнив параметр текстом <code>novalue</code>. Для полного выключения полосы надо так же заполнить параметр ''Герб''.
* ''описание_флага'' — Если не задано, по умолчанию отображается подпись Флаг. Подпись особенно полезна, если государство в разное время имело разл. флаги.
* ''Герб'' — герб территории. Параметр поддерживает импорт викиданных. Есть возможность [[ВП:ЛЖЕГЕРБ|выключить]], заполнив параметр текстом <code>novalue</code>. Для полного выключения полосы надо так же заполнить параметр ''Флаг''.
* ''описание_герба'' — Если не задано, по умолчанию отображается подпись Герб. Подпись особенно полезна, если государство в разное время имело разл. гербы.
* ''Карта'' — карта территории, желательно, по наиболее позднему состоянию. Параметр поддерживает импорт викиданных.
* ''размер'' — необязательное поле, по умолчанию = 270px
* ''Описание'' — описание карты, заметки.
* ''Девиз'' — девиз правящего дома либо государства.
* ''type_before'' — если этот параметр присутствует в шаблоне, то необходимо указать примерно следующее: «Государства-основатели», иначе удалите его, автоматически будет указано: «Предшественники».
* ''p1'' — название административной единицы, существовавшей на данной территории до создания предмета статьи (станет ссылкой).
* ''flag_p1'' — флаг административной единицы, существовавшей на данной территории до создания предмета статьи.
* ''image_pN '' — гербы и другие изображения, для которых нежелательна рамка (в формате <nowiki>[[File:...|Npx]]</nowiki>)
* ''s1'' — название административной единицы, существовавшей на данной территории после упразднения предмета статьи (станет ссылкой).
* ''flag_s1'' — флаг административной единицы, существовавшей на данной территории после упразднения предмета статьи.
* ''image_sN '' — гербы и другие изображения, для которых нежелательна рамка (в формате <nowiki>[[File:...|Npx]]</nowiki>)
* ''pN'' — другие предшественники (если более четырёх, используйте параметры «До» и «После»).
* ''flag_sN'' — флаги государств-предшественников.
* ''Образовано'' — год образования административной единицы. Параметр поддерживает импорт викиданных.
* ''ликвидировано'' — год прекращения существования административной единицы. Параметр поддерживает импорт викиданных.
* ''type_after'' — если этот параметр присутствует в шаблоне, то необходимо указать примерно следующее: «Государства после распада…», иначе удалите его, автоматически будет указано: «Преемники».
* ''pN'' — другие преемники (если более четырёх, используйте параметры «До» и «После»).
* ''flag_pN'' — флаги государств-преемников.
* ''Столица'' — административный центр территории. Параметр поддерживает импорт викиданных.
* ''Валюта'' — денежная единица данной территории. Параметр поддерживает импорт викиданных.
* ''Города'' — крупнейшие города данной территории.
* ''Язык'' — официальный язык территории. Параметр поддерживает импорт викиданных.
* ''Форма_правления'' — форма правления на данной территории. Параметр поддерживает импорт викиданных.
* ''титул_правителей'' — титулы правителей, заданных в параметрах правитель N. Например: «Короли». Если правители имели различные титулы, можно воспользоваться более общей формулировкой, например: «Основные правители».
* ''титул_правителейN'' — используется при изменении титула последующего правителя.
* ''правительN'' — имя правителя N
* ''год_правителяN'' — годы правления правителя N
* ''Дополнительный_параметр1, 2'' — название параметра.
* ''Содержимое_параметра1, 2'' — содержимое параметра.
* ''ЭтапN'' — название этапа в истории государства (до 11).
* ''ДатаN'' — дата начала этапа (до 11).
* ''ГодN'' — год начала этапа (до 11).
* ''До'' — название административной единицы, существовавшей на данной территории до создания предмета статьи.
* ''После'' — название административной единицы, существовавшей на данной территории после упразднения предмета статьи.
* ''дN'' — другие предшественники (до 7).
* ''пN'' — другие преемники (до 7).
* ''прим'' — примечания.
* ''викисклад'' — категория на Викискладе.
<includeonly>
[[Категория:Шаблоны-карточки:Географические объекты]]
[[Категория:Шаблоны-карточки:История]]
</includeonly>
56637e0862b3c305ebd1643f0787f74a89bf78cf
Модуль:Navbox
828
82
138
2024-02-23T14:27:31Z
ruwiki>Stjn
0
переход на [[модуль:Navbar]]
Scribunto
text/plain
--
-- Реализует {{навигационная таблица}}, {{подгруппы навигационной таблицы}} и {{навигационная таблица с блоками}}.
-- Основной объём кода заимствован из английского Module:Navbox.
--
local p = {}
local navbar = require('Module:Navbar')._ruwikiNavbar
local getArgs -- lazily initialized
local yesno -- lazily initialized
local styleratio
local ODD_EVEN_MARKER = '\127_ODDEVEN_\127'
local RESTART_MARKER = '\127_ODDEVEN0_\127'
local REGEX_MARKER = '\127_ODDEVEN(%d?)_\127'
-- общие параметры для всех шаблонов
local commonAliases = {
name = {'name', 'имя'},
navigation = {'navigation', 'навигация'},
navbar = {'navbar', 'ссылка_на_просмотр'},
state = {'state'},
orphan = {'orphan'},
tracking = {'tracking'},
border = {'border', 1},
title = {'title', 'заголовок'},
titlegroup = {'titlegroup'},
above = {'above', 'вверху'},
image = {'image', 'изображение'},
imageleft = {'imageleft', 'изображение2', 'изображение_слева'},
below = {'below', 'внизу'},
bodyclass = {'bodyclass', 'класс_тела'},
titleclass = {'titleclass', 'класс_заголовка'},
titlegroupclass = {'titlegroupclass'},
aboveclass = {'aboveclass', 'класс_вверху'},
belowclass = {'belowclass', 'класс_внизу'},
groupclass = {'groupclass', 'класс_групп'},
listclass = {'listclass', 'класс_списков'},
imageclass = {'imageclass', 'класс_изображения'},
basestyle = {'basestyle', 'стиль', 'стиль_базовый'},
bodystyle = {'style', 'bodystyle', 'стиль_тела'},
titlestyle = {'titlestyle', 'стиль_основного_заголовка', 'стиль_заголовка'},
titlegroupstyle = {'titlegroupstyle'},
innerstyle = {'innerstyle'},
abovestyle = {'abovestyle', 'стиль_вверху'},
belowstyle = {'belowstyle', 'стиль_внизу'},
imagestyle = {'imagestyle', 'стиль_изображения'},
imageleftstyle = {'imageleftstyle', 'imagestyle2', 'стиль_изображения_слева'},
}
-- параметры {{навигационная таблица}} и {{подгруппы навигационной таблицы}}
local standardAliases = {
groupstyle = {'groupstyle', 'стиль_заголовков', 'стиль_групп'},
liststyle = {'liststyle', 'стиль_списков'},
evenodd = {'evenodd', 'чётные_нечётные', 'четные_нечетные'},
groupwidth = {'groupwidth', 'ширина_групп'},
listpadding = {'listpadding', 'отступ_списков'},
}
-- параметры {{навигационная таблица}} и {{подгруппы навигационной таблицы}} с нумерацией
local standardElementAliases = {
group = {'group%s', 'заголовок%s', 'группа%s'},
list = {'list%s', 'список%s'},
groupstyle = {'group%sstyle', 'стиль_заголовка%s', 'стиль_группы%s'},
listclass = {'list%sclass', 'класс%sсписка', 'класс_списка%s'},
liststyle = {'list%sstyle', 'стиль_списка%s'},
listpadding = {'list%spadding'}
}
-- параметры {{навигационная таблица с блоками}}
-- с нижнего подчеркивания начинаются параметры, конфликтующие с standardAliases
local groupsParentAliases = {
selected = {'selected', 'открытый_блок', 'развернуть'},
secttitlestyle = {'secttitlestyle', 'стиль_заголовков'},
_groupstyle = {'groupstyle', 'стиль_блоков'},
_liststyle = {'liststyle', 'стиль_списков', 'contentstyle'},
_listpadding = {'listpadding', 'отступ_списка', 'отступ_списков'}
}
-- параметры {{навигационная таблица с блоками}} с нумерацией
local groupsChildAliases = {
groupname = {'abbr%s', 'имя_блока%s', 'аббр%s'},
state = {'state%s'},
title = {'group%s', 'блок%s', 'заголовок%s', 'группа%s', 'sect%s', 'section%s', 'секция%s'},
list1 = {'list%s', 'список%s', 'content%s'},
image = {'image%s', 'изображение%s'},
imageleft = {'imageleft%s', 'изображение_слева%s'},
secttitlestyle = {'sect%stitlestyle', 'стиль%sзаголовка', 'стиль_секции%s'},
groupstyle = {'group%sstyle', 'стиль%sблока', 'стиль_группы%s', 'стиль_блока%s'},
listclass = {'list%sclass', 'класс%sсписка', 'класс_списка%s'},
liststyle = {'list%sstyle', 'стиль%sсписка', 'стиль_списка%s', 'content%sstyle'},
color = {'цвет%s'}
}
local function checkAliases(args, aliases, index)
for _, alias in ipairs(aliases) do
local arg
if index then
arg = args[string.format(alias, index)]
else
arg = args[alias]
end
if arg then
return arg
end
end
return nil
end
local function checkElAliases(args, name, index)
return checkAliases(args, standardElementAliases[name], index)
end
local function concatStyles(t)
local res
for k, v in pairs(t) do
if v then
res = res and res .. ';' .. v or v
end
end
return res
end
local function striped(wikitext, args)
-- Return wikitext with markers replaced for odd/even striping.
-- Child (subgroup) navboxes are flagged with a category that is removed
-- by parent navboxes. The result is that the category shows all pages
-- where a child navbox is not contained in a parent navbox.
local orphanCat = '[[Категория:Навигационные шаблоны без родителя]]'
if args.border == 'subgroup' and args.orphan ~= 'yes' then
-- No change; striping occurs in outermost navbox.
return wikitext .. orphanCat
end
local first, second = 'odd', 'even'
if args.evenodd then
if args.evenodd == 'swap' then
first, second = second, first
else
first = args.evenodd
second = first
end
end
local changer
if first == second then
changer = first
else
local index = 0
changer = function (code)
if code == '0' then
-- Current occurrence is for a group before a nested table.
-- Set it to first as a valid although pointless class.
-- The next occurrence will be the first row after a title
-- in a subgroup and will also be first.
index = 0
return first
end
index = index + 1
return index % 2 == 1 and first or second
end
end
local regex = orphanCat:gsub('([%[%]])', '%%%1')
return (wikitext:gsub(regex, ''):gsub(REGEX_MARKER, changer)) -- () omits gsub count
end
local function addNewline(s)
if s:match('^[*:;#]') or s:match('^{|') then
return '\n' .. s ..'\n'
else
return s
end
end
local function renderNavBar(titleCell, args)
local currentFrame = mw.getCurrentFrame()
if args.navbar ~= 'off' and args.navbar ~= 'plain'
and (args.name or not currentFrame:getParent():getTitle():gsub('/песочница$', '') == 'Шаблон:Навигационная таблица') then
--- Gear creation
titleCell
:tag('span')
:addClass('navbox-gear')
:css('float', 'left')
:css('text-align', 'left')
:css('width', '5em')
:css('margin-right', '0.5em')
:wikitext(navbar{
args.name,
['fontstyle'] = args.titlestyle or args.basestyle
})
end
end
--
-- Title row
--
local function renderTitleRow(tbl, args)
if not args.title then return end
local titleRow = tbl:tag('tr')
if args.titlegroup then
titleRow
:tag('th')
:attr('scope', 'row')
:addClass('navbox-group')
:addClass(args.titlegroupclass)
:cssText(args.basestyle)
:cssText(args.groupstyle)
:cssText(args.titlegroupstyle)
:wikitext(args.titlegroup)
end
local titleCell = titleRow:tag('th'):attr('scope', 'colgroup')
if args.titlegroup then
titleCell
:css('border-left', '2px solid #fdfdfd')
:css('width', '100%')
end
local titleColspan = 2
if args.imageleft then titleColspan = titleColspan + 1 end
if args.image then titleColspan = titleColspan + 1 end
if args.titlegroup then titleColspan = titleColspan - 1 end
titleCell
:cssText(args.basestyle)
:cssText(args.titlestyle)
:addClass('navbox-title')
:attr('colspan', titleColspan)
renderNavBar(titleCell, args)
titleCell
:tag('div')
:attr('id', mw.uri.anchorEncode(args.title))
:addClass(args.titleclass)
:css('font-size', '114%')
:css('margin', '0 5em')
:wikitext(addNewline(args.title))
end
--
-- Above/Below rows
--
local function getAboveBelowColspan(args)
local ret = 2
if args.imageleft then ret = ret + 1 end
if args.image then ret = ret + 1 end
return ret
end
local function renderAboveRow(tbl, args)
if not args.above then return end
tbl:tag('tr')
:tag('td')
:addClass('navbox-abovebelow')
:addClass(args.aboveclass)
:cssText(args.basestyle)
:cssText(args.abovestyle)
:attr('colspan', getAboveBelowColspan(args))
:tag('div')
:wikitext(addNewline(args.above))
end
local function renderBelowRow(tbl, args)
if not args.below then return end
tbl:tag('tr')
:tag('td')
:addClass('navbox-abovebelow')
:addClass(args.belowclass)
:cssText(args.basestyle)
:cssText(args.belowstyle)
:attr('colspan', getAboveBelowColspan(args))
:tag('div')
:wikitext(addNewline(args.below))
end
--
-- List rows
--
local function haveSubgroups(args)
for i = 1, 23 do
if checkElAliases(args, 'group', i) and checkElAliases(args, 'list', i) then
return true
end
end
return false
end
local function renderListRow(tbl, args, index, rowspan, rowArgs)
local row = tbl:tag('tr')
if index == 1 and args.imageleft then
row
:tag('td')
:addClass('navbox-image')
:addClass(args.imageclass)
:css('width', '1px')
:css('padding', '0px 7px 0px 0px')
:cssText(args.imageleftstyle)
:attr('rowspan', rowspan)
:tag('div')
:wikitext(addNewline(args.imageleft))
end
if rowArgs.group then
local groupCell = row:tag('th')
groupCell
:attr('scope', 'row')
:addClass('navbox-group')
:addClass(args.groupclass)
:cssText(args.basestyle)
:css('width', args.groupwidth or '1px') -- If groupwidth not specified, minimize width
groupCell
:cssText(args.groupstyle)
:cssText(rowArgs.groupstyle)
:wikitext(rowArgs.group)
end
local listCell = row:tag('td')
if rowArgs.group then
listCell
:css('text-align', 'left')
:css('border-left-width', '2px')
:css('border-left-style', 'solid')
else
if haveSubgroups(args) then
listCell
:attr('colspan', 2)
end
end
if not args.groupwidth then
listCell:css('width', '100%')
end
local listText = rowArgs.list
local oddEven = ODD_EVEN_MARKER
if listText:sub(1, 12) == '</div><table' then
-- Assume list text is for a subgroup navbox so no automatic striping for this row.
oddEven = listText:find('<th[^>]*"navbox%-title"') and RESTART_MARKER or 'odd'
end
listCell
:css('padding', '0px')
:cssText(args.liststyle)
:cssText(rowArgs.liststyle)
:addClass('navbox-list')
:addClass('navbox-' .. oddEven)
:addClass(args.listclass)
:addClass(rowArgs.listclass)
:tag('div')
:css('padding', rowArgs.listpadding or args.listpadding or '0em 0.25em')
:wikitext(addNewline(listText))
if index == 1 and args.image then
row
:tag('td')
:addClass('navbox-image')
:addClass(args.imageclass)
:css('width', '1px')
:css('padding', '0px 0px 0px 7px')
:cssText(args.imagestyle)
:attr('rowspan', rowspan)
:tag('div')
:wikitext(addNewline(args.image))
end
end
--
-- Tracking categories
--
local function needsChangetoSubgroups(args)
for i = 1, 23 do
if (checkElAliases(args, 'group', i)) and not (checkElAliases(args, 'list', i)) then
return true
end
end
return false
end
local function needsHorizontalLists(args)
if args.border == 'subgroup' or args.tracking == 'no' then
return false
end
local listClasses = {
['plainlist'] = true, ['hlist'] = true, ['hlist hnum'] = true,
['hlist hwrap'] = true, ['hlist vcard'] = true, ['vcard hlist'] = true,
['hlist vevent'] = true, ['hlist hlist-items-nowrap'] = true, ['hlist-items-nowrap'] = true,
}
return not (listClasses[args.listclass] or listClasses[args.bodyclass])
end
-- local function hasBackgroundColors()
-- return mw.ustring.match(titlestyle or '','background') or mw.ustring.match(groupstyle or '','background') or mw.ustring.match(basestyle or '','background')
-- end
local function isIllegible(args)
if not styleratio then
styleratio = require('Module:Color contrast')._styleratio
end
for key, style in pairs(args) do
if tostring(key):match("style$") or tostring(key):match("^стиль") then
if styleratio{mw.text.unstripNoWiki(style)} < 4.5 then
return true
end
end
end
return false
end
local function getTrackingCategories(args)
local cats = {}
if needsChangetoSubgroups(args) then table.insert(cats, 'Навигационные шаблоны с ошибочным использованием заголовков') end
if needsHorizontalLists(args) then table.insert(cats, 'Навигационные шаблоны без горизонтальных списков') end
if isIllegible(args) then table.insert(cats, 'Потенциально нечитаемые навигационные шаблоны') end
return cats
end
local function renderTrackingCategories(builder, args)
local title = mw.title.getCurrentTitle()
if title.namespace ~= 10 then return end -- not in template space
local subpage = title.subpageText
if subpage == 'doc' or subpage == 'песочница' or subpage == 'тесты' then return end
for i, cat in ipairs(getTrackingCategories(args)) do
builder:wikitext('[[Категория:' .. cat .. ']]')
end
end
--
-- Main navbox tables
--
local function renderMainTable(args, listnums)
local tbl = mw.html.create('table')
:addClass('nowraplinks')
:addClass(args.bodyclass)
if args.title and (args.state ~= 'plain' and args.state ~= 'off') then
tbl
:addClass('collapsible')
:addClass(args.state or 'autocollapse')
end
tbl:css('border-spacing', 0)
if args.border == 'subgroup' or args.border == 'none' then
tbl
:addClass('navbox-subgroup')
:cssText(args.bodystyle)
else -- regular navbox - bodystyle and style will be applied to the wrapper table
tbl
:addClass('navbox-inner')
:css('background', 'transparent')
:css('color', 'inherit')
end
tbl:cssText(args.innerstyle)
renderTitleRow(tbl, args)
renderAboveRow(tbl, args)
for i, listnum in ipairs(listnums) do
local rowArgs = {
group = checkElAliases(args, 'group', listnum),
list = checkElAliases(args, 'list', listnum),
groupstyle = checkElAliases(args, 'groupstyle', listnum),
listclass = checkElAliases(args, 'listclass', listnum),
liststyle = checkElAliases(args, 'liststyle', listnum),
listpadding = checkElAliases(args, 'listpadding', listnum)
}
renderListRow(tbl, args, i, #listnums, rowArgs)
end
renderBelowRow(tbl, args)
return tbl
end
-- Read the arguments in the order they'll be output in, to make references number in the right order.
local function readInTheRightOrder(args, groupAliases, listAliases)
local _
_ = checkAliases(args, commonAliases.title)
_ = checkAliases(args, commonAliases.above)
for i = 1, 23 do
_ = checkAliases(args, groupAliases, i)
_ = checkAliases(args, listAliases, i)
end
_ = checkAliases(args, commonAliases.below)
end
function p._navbox(args)
if not yesno then
yesno = require('Module:Yesno')
end
local listnums = {}
for k, v in pairs(args) do
local listnum = ('' .. k):match('^list(%d+)$') or ('' .. k):match('^список(%d+)$')
if listnum then table.insert(listnums, tonumber(listnum)) end
end
table.sort(listnums)
args.border = mw.text.trim(args.border or args[1] or '')
if args.border == 'child' then
args.border = 'subgroup'
end
for argname, aliasesList in pairs(commonAliases) do
args[argname] = checkAliases(args, aliasesList)
end
for argname, aliasesList in pairs(standardAliases) do
args[argname] = checkAliases(args, aliasesList)
end
args.navigation = yesno(args.navigation, '')
-- render the main body of the navbox
local tbl = renderMainTable(args, listnums)
-- render the appropriate wrapper around the navbox, depending on the border param
local res = mw.html.create()
if args.border == 'none' then
local nav = res:tag('div')
:attr('role', 'navigation')
:node(tbl)
if args.title then
nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title))
else
nav:attr('aria-label', 'Навигационный шаблон')
end
if args.name and args.name ~= '-' then
nav:attr('data-name', args.name)
end
if args.navigation == true then
nav:attr('data-navboxnavigation', '1')
elseif args.navigation == false then
nav:attr('data-navboxnavigation', '0')
end
elseif args.border == 'subgroup' then
-- We assume that this navbox is being rendered in a list cell of a parent navbox, and is
-- therefore inside a div with padding:0em 0.25em. We start with a </div> to avoid the
-- padding being applied, and at the end add a <div> to balance out the parent's </div>
res
:wikitext('</div>') -- XXX: hack due to lack of unclosed support in mw.html.
:node(tbl)
:wikitext('<div>') -- XXX: hack due to lack of unclosed support in mw.html.
else
local nav = res:tag('div')
:attr('role', 'navigation')
:addClass('navbox')
:cssText(args.bodystyle)
:node(tbl)
if args.title then
nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title))
else
nav:attr('aria-label', 'Навигационный шаблон')
end
if args.name and args.name ~= '-' then
nav:attr('data-name', args.name)
end
if args.navigation == true then
nav:attr('data-navboxnavigation', '1')
elseif args.navigation == false then
nav:attr('data-navboxnavigation', '0')
end
end
renderTrackingCategories(res, args)
return striped(tostring(res), args)
end
function p.navbox(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
if not yesno then
yesno = require('Module:Yesno')
end
args = getArgs(frame, {wrappers = {'Шаблон:Навигационная таблица', 'Шаблон:Подгруппы навигационной таблицы'}})
if frame.args.border then
-- This allows Template:Navbox_subgroup to use {{#invoke:Navbox|navbox|border=...}}.
args.border = frame.args.border
end
readInTheRightOrder(args, standardElementAliases.group, standardElementAliases.list)
return p._navbox(args)
end
function p.navboxWithCollapsibleGroups(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
local args = getArgs(frame, {wrappers = {'Шаблон:Навигационная таблица с блоками'}})
readInTheRightOrder(args, groupsChildAliases.title, groupsChildAliases.list1)
local parent = {}
for argname, aliasesList in pairs(commonAliases) do
parent[argname] = checkAliases(args, aliasesList)
end
for argname, aliasesList in pairs(groupsParentAliases) do
parent[argname] = checkAliases(args, aliasesList)
end
for i = 1, 20 do
local child = {}
for argname, aliasesList in pairs(groupsChildAliases) do
child[argname] = checkAliases(args, aliasesList, i)
end
child.color = child.color and string.format('background:%s;', child.color) or ''
child.border = 'child'
child.navbar = 'plain'
if parent.selected and parent.selected == child.groupname then
child.state = 'uncollapsed'
end
child.state = child.state or 'collapsed'
child.basestyle = concatStyles{parent.basestyle, parent.secttitlestyle, child.secttitlestyle}
child.titlestyle = concatStyles{parent._groupstyle, child.groupstyle, child.color}
child.liststyle = concatStyles{parent._liststyle, child.liststyle}
child.lispadding = parent._listpadding
if child.title then
parent['list' .. i] = p._navbox(child)
else
parent['list' .. i] = child.list1
end
end
return p._navbox(parent)
end
return p
cf72974326d19e1d4d58d2d00766b944b3ca0944
Шаблон:TOC right/styles.css
10
195
436
2024-02-23T16:55:08Z
ruwiki>Stjn
0
не отображать в новом Векторе
sanitized-css
text/css
@media (min-width: 720px) {
body:not(.skin-minerva) .ts-TOC_right {
margin-left: 1em;
margin-bottom: 0.5em;
float: right;
clear: right;
}
}
@media (max-width: 719px) {
.ts-TOC_right {
width: auto !important;
max-width: none !important;
clear: none !important;
}
}
body.skin-vector-2022 .ts-TOC_right {
display: none;
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
710a99f2d4d2a78eb7a6f884538055bb6ac67c99
Шаблон:Навигационная таблица
10
215
478
2024-02-26T11:53:15Z
ruwiki>Stjn
0
тоже может иметь эти значения
wikitext
text/x-wiki
<includeonly>{{#invoke:Navbox|navbox}}</includeonly>{{#ifeq: {{NAMESPACE}} | Шаблон
| {{#switch: {{{1|{{{border|}}}}}}
| child | subgroup | none =
| {{#ifeq: {{{имя|{{{name|}}}}}} | {{PAGENAME}}
|
| {{#if:{{yesno|{{{tracking|}}}|no=1|yes=|blank=}}
|
| {{#if: {{{имя|{{{name|}}}}}}
| {{#ifeq:{{ROOTPAGENAME}}|Работа недели||{{no-doc|[[Категория:Навигационные шаблоны, у которых нужно проверить параметр Имя]]}}}}
| [[Категория:Навигационные шаблоны, у которых предположительно недостаёт параметра Имя]]
}}
}}
}}
}}
}}<noinclude>
{{doc}}
</noinclude>
b1c7f6e61d3b9cdd1daaf4d95e30e299a1d9eb5c
Модуль:Delink
828
264
689
2024-02-28T16:27:08Z
ruwiki>Dima st bk
0
sync with enwiki, see authors of this version https://en.wikipedia.org/w/index.php?title=Module:Delink&oldid=1208348327
Scribunto
text/plain
-- This module de-links most wikitext.
require("strict")
local yesno = require("Module:Yesno")
local p = {}
local getArgs
local function delinkReversePipeTrick(s)
if s:match("^%[%[|.*[|\n]") then -- Check for newlines or multiple pipes.
return s
end
return s:match("%[%[|(.*)%]%]")
end
local function delinkPipeTrick(s)
-- We need to deal with colons, brackets, and commas, per [[Help:Pipe trick]].
-- First, remove the text before the first colon, if any.
if s:match(":") then
s = s:match("%[%[.-:(.*)|%]%]")
-- If there are no colons, grab all of the text apart from the square brackets and the pipe.
else
s = s:match("%[%[(.*)|%]%]")
end
-- Next up, brackets and commas.
if s:match("%(.-%)$") then -- Brackets trump commas.
s = s:match("(.-) ?%(.-%)$")
elseif s:match(",") then -- If there are no brackets, display only the text before the first comma.
s = s:match("(.-),.*$")
end
return s
end
-- Return wikilink target |wikilinks=target
local function getDelinkedTarget(s)
local result = s
-- Deal with the reverse pipe trick.
if result:match("%[%[|") then
return delinkReversePipeTrick(result)
end
result = mw.uri.decode(result, "PATH") -- decode percent-encoded entities. Leave underscores and plus signs.
result = mw.text.decode(result, true) -- decode HTML entities.
-- Check for bad titles. To do this we need to find the
-- title area of the link, i.e. the part before any pipes.
local target_area
if result:match("|") then -- Find if we're dealing with a piped link.
target_area = result:match("^%[%[(.-)|.*%]%]")
else
target_area = result:match("^%[%[(.-)%]%]")
end
-- Check for bad characters.
if mw.ustring.match(target_area, "[%[%]<>{}%%%c\n]") and mw.ustring.match(target_area, "[%[%]<>{}%%%c\n]") ~= "?" then
return s
end
return target_area
end
local function getDelinkedLabel(s)
local result = s
-- Deal with the reverse pipe trick.
if result:match("%[%[|") then
return delinkReversePipeTrick(result)
end
result = mw.uri.decode(result, "PATH") -- decode percent-encoded entities. Leave underscores and plus signs.
result = mw.text.decode(result, true) -- decode HTML entities.
-- Check for bad titles. To do this we need to find the
-- title area of the link, i.e. the part before any pipes.
local target_area
if result:match("|") then -- Find if we're dealing with a piped link.
target_area = result:match("^%[%[(.-)|.*%]%]")
else
target_area = result:match("^%[%[(.-)%]%]")
end
-- Check for bad characters.
if mw.ustring.match(target_area, "[%[%]<>{}%%%c\n]") and mw.ustring.match(target_area, "[%[%]<>{}%%%c\n]") ~= "?" then
return s
end
-- Check for categories, interwikis, and files.
local colon_prefix = result:match("%[%[(.-):.*%]%]") or "" -- Get the text before the first colon.
local ns = mw.site.namespaces[colon_prefix] -- see if this is a known namespace
if mw.language.isKnownLanguageTag(colon_prefix) or (ns and (ns.canonicalName == "File" or ns.canonicalName == "Category")) then
return ""
end
-- Remove the colon if the link is using the [[Help:Colon trick]].
if result:match("%[%[:") then
result = "[[" .. result:match("%[%[:(.*%]%])")
end
-- Deal with links using the [[Help:Pipe trick]].
if mw.ustring.match(result, "^%[%[[^|]*|%]%]") then
return delinkPipeTrick(result)
end
-- Find the display area of the wikilink
if result:match("|") then -- Find if we're dealing with a piped link.
result = result:match("^%[%[.-|(.+)%]%]")
-- Remove new lines from the display of multiline piped links,
-- where the pipe is before the first new line.
result = result:gsub("\n", "")
else
result = result:match("^%[%[(.-)%]%]")
end
return result
end
local function delinkURL(s)
-- Assume we have already delinked internal wikilinks, and that
-- we have been passed some text between two square brackets [foo].
-- If the text contains a line break it is not formatted as a URL, regardless of other content.
if s:match("\n") then
return s
end
-- Check if the text has a valid URL prefix and at least one valid URL character.
local valid_url_prefixes = {"//", "http://", "https://", "ftp://", "gopher://", "mailto:", "news:", "irc://"}
local url_prefix
for _ ,v in ipairs(valid_url_prefixes) do
if mw.ustring.match(s, '^%[' .. v ..'[^"%s].*%]' ) then
url_prefix = v
break
end
end
-- Get display text
if not url_prefix then
return s
end
s = s:match("^%[" .. url_prefix .. "(.*)%]") -- Grab all of the text after the URL prefix and before the final square bracket.
s = s:match('^.-(["<> ].*)') or "" -- Grab all of the text after the first URL separator character ("<> ).
s = mw.ustring.match(s, "^%s*(%S.*)$") or "" -- If the separating character was a space, trim it off.
local s_decoded = mw.text.decode(s, true)
if mw.ustring.match(s_decoded, "%c") then
return s
end
return s_decoded
end
local function delinkLinkClass(text, pattern, delinkFunction)
if type(text) ~= "string" then
error("Attempt to de-link non-string input.", 2)
end
if type(pattern) ~= "string" or mw.ustring.sub(pattern, 1, 1) ~= "^" then
error('Invalid pattern detected. Patterns must begin with "^".', 2)
end
-- Iterate over the text string, and replace any matched text. using the
-- delink function. We need to iterate character by character rather
-- than just use gsub, otherwise nested links aren't detected properly.
local result = ""
while text ~= "" do
-- Replace text using one iteration of gsub.
text = mw.ustring.gsub(text, pattern, delinkFunction, 1)
-- Append the left-most character to the result string.
result = result .. mw.ustring.sub(text, 1, 1)
text = mw.ustring.sub(text, 2, -1)
end
return result
end
function p._delink(args)
local text = args[1] or ""
if yesno(args.markers) == true then
text = mw.text.killMarkers(text) -- [[Help:Strip markers]]
end
if yesno(args.refs) == true then
-- Remove any [[Help:Strip markers]] representing ref tags. In most situations
-- this is not a good idea - only use it if you know what you are doing!
text = mw.ustring.gsub(text, "UNIQ%w*%-ref%-%d*%-QINU", "")
end
if not (yesno(args.comments) == false) then
text = text:gsub("<!%-%-.-%-%->", "") -- Remove html comments.
end
if not (yesno(args.wikilinks) == false) and args.wikilinks ~= "target" then
-- De-link wikilinks and return the label portion of the wikilink.
text = delinkLinkClass(text, "^%[%[.-%]%]", getDelinkedLabel)
elseif args.wikilinks == "target" then
-- De-link wikilinks and return the target portions of the wikilink.
text = delinkLinkClass(text, "^%[%[.-%]%]", getDelinkedTarget)
end
if not (yesno(args.urls) == false) then
text = delinkLinkClass(text, "^%[.-%]", delinkURL) -- De-link URLs.
end
if not (yesno(args.whitespace) == false) then
-- Replace single new lines with a single space, but leave double new lines
-- and new lines only containing spaces or tabs before a second new line.
text = mw.ustring.gsub(text, "([^\n \t][ \t]*)\n([ \t]*[^\n \t])", "%1 %2")
text = text:gsub("[ \t]+", " ") -- Remove extra tabs and spaces.
end
return text
end
function p.delink(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
return p._delink(getArgs(frame, {wrappers = 'Template:Delink'}))
end
return p
eb6cae0d369f288b0b1600633d9bf7874cefdcbc
Модуль:Message box
828
21
136
2024-03-25T18:05:03Z
ruwiki>Stjn
0
fix
Scribunto
text/plain
-- This is a meta-module for producing message box templates, including
-- {{mbox}}, {{ambox}}, {{imbox}}, {{tmbox}}, {{ombox}}, {{cmbox}} and {{fmbox}}.
-- Load necessary modules.
require('strict')
local getArgs
local categoryHandler = require('Module:Category handler')._main
local yesno = require('Module:Yesno')
local boxDate = require('Module:Calendar').bxDate;
-- Get a language object for formatDate and ucfirst.
local lang = mw.language.getContentLanguage()
-- Define constants
local CONFIG_MODULE = 'Module:Message box/configuration'
--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------
local function getTitleObject(...)
-- Get the title object, passing the function through pcall
-- in case we are over the expensive function count limit.
local success, title = pcall(mw.title.new, ...)
if success then
return title
end
end
local function union(t1, t2)
-- Returns the union of two arrays.
local vals = {}
for i, v in ipairs(t1) do
vals[v] = true
end
for i, v in ipairs(t2) do
vals[v] = true
end
local ret = {}
for k in pairs(vals) do
table.insert(ret, k)
end
table.sort(ret)
return ret
end
local function getArgNums(args, prefix)
local nums = {}
for k, v in pairs(args) do
local num = mw.ustring.match(tostring(k), '^' .. prefix .. '([1-9]%d*)$')
if num then
table.insert(nums, tonumber(num))
end
end
table.sort(nums)
return nums
end
-- локальная обёртка, игнорирует таблицу с номерами дня, месяца и года
local function formatDate(txtDateIn, strFormat, params)
local txtDateOut, date, status = boxDate(txtDateIn, strFormat, params)
if status.brk then
return error(status.errorText)
else
return txtDateOut
end
end
--------------------------------------------------------------------------------
-- Box class definition
--------------------------------------------------------------------------------
local MessageBox = {}
MessageBox.__index = MessageBox
function MessageBox.new(boxType, args, cfg)
args = args or {}
local obj = {}
-- Set the title object and the namespace.
obj.title = getTitleObject(args.page) or mw.title.getCurrentTitle()
-- Set the config for our box type.
obj.cfg = cfg[boxType]
if not obj.cfg then
local ns = obj.title.namespace
-- boxType is "mbox" or invalid input
if ns == 0 then
obj.cfg = cfg.ambox -- main namespace
elseif ns == 6 then
obj.cfg = cfg.imbox -- file namespace
elseif ns == 14 then
obj.cfg = cfg.cmbox -- category namespace
else
local nsTable = mw.site.namespaces[ns]
if nsTable and nsTable.isTalk then
obj.cfg = cfg.tmbox -- any talk namespace
else
obj.cfg = cfg.ombox -- other namespaces or invalid input
end
end
end
-- Set the arguments, and remove all blank arguments except for the ones
-- listed in cfg.allowBlankParams.
do
local newArgs = {}
for k, v in pairs(args) do
if v ~= '' then
newArgs[k] = v
end
end
for i, param in ipairs(obj.cfg.allowBlankParams or {}) do
newArgs[param] = args[param]
end
obj.args = newArgs
end
-- Define internal data structure.
obj.categories = {}
obj.classes = {}
return setmetatable(obj, MessageBox)
end
function MessageBox:addCat(ns, cat, sort)
if not cat then
return nil
end
if sort then
cat = string.format('[[Категория:%s|%s]]', cat, sort)
else
cat = string.format('[[Категория:%s]]', cat)
end
self.categories[ns] = self.categories[ns] or {}
table.insert(self.categories[ns], cat)
end
function MessageBox:addClass(class)
if not class then
return nil
end
table.insert(self.classes, class)
end
function MessageBox:setParameters()
local args = self.args
local cfg = self.cfg
-- Get type data.
self.type = args.type
local typeData = cfg.types[self.type]
self.invalidTypeError = cfg.showInvalidTypeError
and self.type
and not typeData
typeData = typeData or cfg.types[cfg.default]
self.typeClass = typeData.class
self.typeImage = typeData.image
-- Find if the box has been wrongly substituted.
self.isSubstituted = cfg.substCheck and args.subst == 'SUBST'
-- Find whether we are using a small message box.
self.isSmall = cfg.allowSmall and (
cfg.smallParam and args.small == cfg.smallParam
or not cfg.smallParam and yesno(args.small)
)
-- Add attributes, classes and styles.
self.id = args.id
self.name = args.name
if self.name then
self:addClass('mbox-' .. string.gsub(self.name,' ','_'))
end
if yesno(args.plainlinks) ~= false then
self:addClass('plainlinks')
end
for _, class in ipairs(cfg.classes or {}) do
self:addClass(class)
end
if self.isSmall then
self:addClass(cfg.smallClass or 'mbox-small')
end
self:addClass(self.typeClass)
self:addClass(args.class)
self.style = args.style
self.attrs = args.attrs
self.dataLabel1 = args['data-label-1']
self.dataLabel2 = args['data-label-2']
self.dataLabel3 = args['data-label-3']
self.dataValue1 = args['data-value-1']
self.dataValue2 = args['data-value-2']
self.dataValue3 = args['data-value-3']
-- Set text style.
self.textstyle = args.textstyle
-- Find if we are on the template page or not. This functionality is only
-- used if useCollapsibleTextFields is set, or if both cfg.templateCategory
-- and cfg.templateCategoryRequireName are set.
self.useCollapsibleTextFields = cfg.useCollapsibleTextFields
if self.useCollapsibleTextFields
or cfg.templateCategory
and cfg.templateCategoryRequireName
then
self.name = args.name
if self.name then
local templateName = mw.ustring.match(
self.name,
'^[tT][eE][mM][pP][lL][aA][tT][eE][%s_]*:[%s_]*(.*)$'
) or self.name
templateName = ('Template:' .. templateName) or ('Шаблон:' .. templateName)
self.templateTitle = getTitleObject(templateName)
end
self.isTemplatePage = self.templateTitle
and mw.title.equals(self.title, self.templateTitle)
end
-- Process data for collapsible text fields. At the moment these are only
-- used in {{ambox}}.
if self.useCollapsibleTextFields then
-- Get the self.issue value.
if self.isSmall and args.smalltext then
self.issue = args.smalltext
else
if args.sect and args.sect ~= '' or nil then
local issue_sect = args.issue_sect
issue_sect = type(issue_sect) == 'string' and issue_sect ~= '' and issue_sect or nil
local text_sect = args.text_sect
text_sect = type(text_sect) == 'string' and text_sect ~= '' and text_sect or nil
local issues = {}
table.insert(issues, issue_sect)
table.insert(issues, text_sect)
self.issue = table.concat(issues, ' ')
else
local issue = args.issue
issue = type(issue) == 'string' and issue ~= '' and issue or nil
local text = args.text
text = type(text) == 'string' and text or nil
local issues = {}
table.insert(issues, issue)
table.insert(issues, text)
self.issue = table.concat(issues, ' ')
end
end
-- Get the self.talk value.
local talk = args.talk
-- Show talk links on the template page or template subpages if the talk
-- parameter is blank.
if talk == ''
and self.templateTitle
and (
mw.title.equals(self.templateTitle, self.title)
or self.title:isSubpageOf(self.templateTitle)
)
then
talk = '#'
elseif talk == '' then
talk = nil
end
if talk then
-- If the talk value is a talk page, make a link to that page. Else
-- assume that it's a section heading, and make a link to the talk
-- page of the current page with that section heading.
local talkTitle = getTitleObject(talk)
local talkArgIsTalkPage = true
if not talkTitle or not talkTitle.isTalkPage then
talkArgIsTalkPage = false
talkTitle = getTitleObject(
self.title.text,
mw.site.namespaces[self.title.namespace].talk.id
)
end
if talkTitle and talkTitle.exists then
local talkText = 'Соответствующую дискуссию можно найти на'
if talkArgIsTalkPage then
talkText = string.format(
'%s [[%s|%s]].',
talkText,
talk,
talkTitle.prefixedText
)
else
talkText = string.format(
'%s [[%s#%s|странице обсуждения]].',
talkText,
talkTitle.prefixedText,
talk
)
end
self.talk = talkText
end
end
-- Get other values.
self.fix = args.fix ~= '' and args.fix or nil
local date
if args.date and args.date ~= '' then
local status, result = pcall(formatDate, args.date)
if status then
date = string.format("(<span class='date'>%s</span>)", result)
else
date = string.format("<span class='error'>(Строка «%s» не является верной датой, пожалуйста, укажите дату в формате <code>ГГГГ-ММ-ДД</code>)</span>", args.date)
end
elseif args.date == '' and self.isTemplatePage then
date = string.format("(<span class='date'>%s</span>)", formatDate( lang:formatDate('Y-m-d') ) ) -- тут возникновения ошибки, связанной с пользовательским вводом, не будет
end
if date then
self.date = string.format(" <span class='mbox-date'>''%s''</span>", date)
end
self.info = args.info
if yesno(args.removalnotice) then
self.removalNotice = cfg.removalNotice
end
if args.shortFix then
self.shortFix = args.shortFix
end
end
-- Set the non-collapsible text field. At the moment this is used by all box
-- types other than ambox, and also by ambox when small=yes.
if self.isSmall then
self.text = args.smalltext or args.text
else
self.text = args.text
self.textsmall = args['text-small']
end
-- Set the below row.
self.below = cfg.below and args.below
-- General image settings.
self.imageCellDiv = not self.isSmall and cfg.imageCellDiv
self.imageEmptyCell = cfg.imageEmptyCell
if cfg.imageEmptyCellStyle then
self.imageEmptyCellStyle = 'border:none;padding:0px;width:1px'
end
-- Left image settings.
local imageLeft = self.isSmall and args.smallimage or args.image
if cfg.imageCheckBlank and imageLeft ~= 'blank' and imageLeft ~= 'none' and imageLeft ~= ''
or not cfg.imageCheckBlank and imageLeft ~= 'none'
then
self.imageLeft = imageLeft
if not imageLeft then
local imageSize = self.isSmall
and (cfg.imageSmallSize or '30x30px')
or cfg.imageSize
or '40x40px'
self.imageLeft = string.format('[[File:%s|%s|alt=]]', self.typeImage
or 'Information icon4.svg', imageSize)
end
end
-- Right image settings.
local imageRight = self.isSmall and args.smallimageright or args.imageright
if not (cfg.imageRightNone and imageRight == 'none') then
self.imageRight = imageRight
end
-- set templatestyles
self.base_templatestyles = cfg.templatestyles
end
function MessageBox:setMainspaceCategories()
local args = self.args
local cfg = self.cfg
local date = nil
if not cfg.allowMainspaceCategories then
return nil
end
local nums = {}
for _, prefix in ipairs{'cat', 'category', 'all'} do
args[prefix .. '1'] = args[prefix]
nums = union(nums, getArgNums(args, prefix))
end
-- The following is roughly equivalent to the old {{Ambox/category}}.
local status, result = pcall(formatDate, args.date, 'xg Y')
if status then
date = result
end
date = type(date) == 'string' and date
local preposition = 'с'
local suffix = 'года'
for _, num in ipairs(nums) do
local mainCat = args['cat' .. tostring(num)]
or args['category' .. tostring(num)]
local allCat = args['all' .. tostring(num)]
mainCat = type(mainCat) == 'string' and mainCat
allCat = type(allCat) == 'string' and allCat
if mainCat and date and date ~= '' then
local catTitle = string.format('%s %s %s %s', mainCat, preposition, date, suffix)
self:addCat(0, catTitle)
catTitle = getTitleObject('Категория:' .. catTitle)
local status, result = pcall(formatDate, args.date)
if not status then
self:addCat(0, 'Википедия:Статьи с недопустимым параметром даты в шаблоне-сообщении')
end
elseif mainCat and (not date or date == '') then
self:addCat(0, mainCat)
end
if allCat then
self:addCat(0, allCat)
end
end
end
function MessageBox:setTemplateCategories()
local args = self.args
local cfg = self.cfg
-- Add template categories.
if cfg.templateCategory then
if cfg.templateCategoryRequireName then
if self.isTemplatePage then
self:addCat(10, cfg.templateCategory)
end
elseif not self.title.isSubpage then
self:addCat(10, cfg.templateCategory)
end
end
-- Add template error categories.
if cfg.templateErrorCategory then
local templateErrorCategory = cfg.templateErrorCategory
local templateCat, templateSort
if not self.name and not self.title.isSubpage then
templateCat = templateErrorCategory
elseif self.isTemplatePage then
local paramsToCheck = cfg.templateErrorParamsToCheck or {}
local count = 0
for i, param in ipairs(paramsToCheck) do
if not args[param] then
count = count + 1
end
end
if count > 0 then
templateCat = templateErrorCategory
templateSort = tostring(count)
end
if self.categoryNums and #self.categoryNums > 0 then
templateCat = templateErrorCategory
templateSort = 'C'
end
end
self:addCat(10, templateCat, templateSort)
end
end
function MessageBox:setAllNamespaceCategories()
-- Set categories for all namespaces.
if self.invalidTypeError then
local allSort = (self.title.namespace == 0 and 'Main:' or '') .. self.title.prefixedText
self:addCat('all', 'Википедия:Необходимо исправить параметр в шаблоне-сообщении', allSort)
end
if self.isSubstituted then
self:addCat('all', 'Википедия:Страницы с ошибочно подставленными шаблонами')
end
if self.isSmall then
self:addCat(0, 'Википедия:Страницы с малыми шаблонами-сообщениями')
end
end
function MessageBox:setCategories()
if self.title.namespace == 0 then
self:setMainspaceCategories()
elseif self.title.namespace == 10 then
self:setTemplateCategories()
end
self:setAllNamespaceCategories()
end
function MessageBox:renderCategories()
-- Convert category tables to strings and pass them through
-- [[Module:Category handler]].
return categoryHandler{
main = table.concat(self.categories[0] or {}),
template = table.concat(self.categories[10] or {}),
all = table.concat(self.categories.all or {}),
nocat = self.args.nocat,
page = self.args.page
}
end
function MessageBox:export()
local root = mw.html.create()
-- Add the subst check error.
if self.isSubstituted and self.name then
root:tag('b')
:addClass('error')
:wikitext(string.format(
'Шаблон <code>%s[[Шаблон:%s|%s]]%s</code> был неккоректно подставлен.',
mw.text.nowiki('{{'), self.name, self.name, mw.text.nowiki('}}')
))
end
-- Conditional TemplateStyles loading
if self.base_templatestyles then
local frame = mw.getCurrentFrame()
root:wikitext(frame:extensionTag{
name = 'templatestyles',
args = { src = self.base_templatestyles },
})
end
-- Create the box table.
local boxTable = root:tag('table')
boxTable:attr('id', self.id or nil)
for i, class in ipairs(self.classes or {}) do
boxTable:addClass(class or nil)
end
boxTable
:cssText(self.style or nil)
:attr('role', 'presentation')
if self.dataLabel1 then
boxTable:attr('data-' .. self.dataLabel1, self.dataValue1)
end
if self.dataLabel2 then
boxTable:attr('data-' .. self.dataLabel2, self.dataValue2)
end
if self.dataLabel3 then
boxTable:attr('data-' .. self.dataLabel3, self.dataValue3)
end
if self.attrs then
boxTable:attr(self.attrs)
end
-- Add the left-hand image.
local row = boxTable:tag('tr')
if self.imageLeft then
local imageLeftCell = row:tag('td'):addClass('mbox-image')
if self.imageCellDiv then
-- If we are using a div, redefine imageLeftCell so that the image
-- is inside it. Divs use style="width: 52px;", which limits the
-- image width to 52px. If any images in a div are wider than that,
-- they may overlap with the text or cause other display problems.
imageLeftCell = imageLeftCell:tag('div'):css('width', '52px')
end
imageLeftCell:wikitext(self.imageLeft or nil)
elseif self.imageEmptyCell then
-- Some message boxes define an empty cell if no image is specified, and
-- some don't. The old template code in templates where empty cells are
-- specified gives the following hint: "No image. Cell with some width
-- or padding necessary for text cell to have 100% width."
row:tag('td')
:addClass('mbox-empty-cell')
:cssText(self.imageEmptyCellStyle or nil)
end
-- Add the text.
local textCell = row:tag('td'):addClass('mbox-text')
if self.useCollapsibleTextFields then
-- The message box uses advanced text parameters that allow things to be
-- collapsible. At the moment, only ambox uses this.
textCell:cssText(self.textstyle or nil)
local textCellDiv = textCell:tag('div')
textCellDiv
:addClass('mbox-text-div')
:wikitext(self.issue or nil)
local textsmallCellDiv = textCell:tag('div')
textsmallCellDiv
:addClass('mbox-textsmall-div hide-when-compact')
:cssText(self.textsmallstyle)
:wikitext(self.textsmall or nil)
if (self.talk or self.fix) and not self.isSmall then
textsmallCellDiv:tag('span')
:addClass('hide-when-compact')
:wikitext(self.fix and (' ' .. self.fix) or nil)
:wikitext(self.talk and (' ' .. self.talk) or nil)
end
if self.textsmall or self.fix or self.talk then
textsmallCellDiv:wikitext(self.date and (' ' .. self.date) or nil)
else
textCellDiv:wikitext(self.date and (' ' .. self.date) or nil)
end
if self.info and not self.isSmall then
textsmallCellDiv
:tag('span')
:addClass('hide-when-compact')
:wikitext(self.info and (' ' .. self.info) or nil)
end
if self.removalNotice then
textsmallCellDiv:tag('small')
:addClass('hide-when-compact')
:tag('i')
:wikitext(string.format(" (%s)", self.removalNotice))
end
if self.shortFix then
textCell:tag('div')
:addClass('mbox-multiply')
:tag('span')
:wikitext(string.format("%s", self.shortFix))
:tag('span')
:wikitext(self.date and (' ' .. self.date) or nil)
end
else
-- Default text formatting - anything goes.
textCell
:cssText(self.textstyle or nil)
:wikitext(self.text or nil)
end
-- Add the right-hand image.
if self.imageRight then
local imageRightCell = row:tag('td'):addClass('mbox-imageright')
if self.imageCellDiv then
-- If we are using a div, redefine imageRightCell so that the image
-- is inside it.
imageRightCell = imageRightCell:tag('div'):css('width', '52px')
end
imageRightCell
:wikitext(self.imageRight or nil)
end
-- Add the below row.
if self.below then
boxTable:tag('tr')
:tag('td')
:attr('colspan', self.imageRight and '3' or '2')
:addClass('mbox-text')
:cssText(self.textstyle or nil)
:wikitext(self.below or nil)
end
-- Add error message for invalid type parameters.
if self.invalidTypeError then
root:tag('div')
:css('text-align', 'center')
:wikitext(string.format(
'Этот шаблон-сообщение использует неверный параметр "type=%s", необходимо исправить.',
self.type or ''
))
end
-- Add categories.
root:wikitext(self:renderCategories() or nil)
return tostring(root)
end
--------------------------------------------------------------------------------
-- Exports
--------------------------------------------------------------------------------
local p, mt = {}, {}
function p._exportClasses()
-- For testing.
return {
MessageBox = MessageBox
}
end
function p.main(boxType, args, cfgTables)
local box = MessageBox.new(boxType, args, cfgTables or mw.loadData(CONFIG_MODULE))
box:setParameters()
box:setCategories()
return box:export()
end
function mt.__index(t, k)
return function (frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
return t.main(k, getArgs(frame, {trim = false, removeBlanks = false}))
end
end
return setmetatable(p, mt)
f2539b657a9cdadde7c0dd5ad270d3095b2bdd54
Шаблон:Очистить кэш
10
179
400
2024-03-27T11:58:48Z
ruwiki>Stjn
0
не помещать на все страницы ежедневную очистку кэша
wikitext
text/x-wiki
<!-- Класс purgelink и атрибут data-pagename используются в [[MediaWiki:Common.js]], чтобы очищать кэш без перехода на отдельную страницу --><span class="noprint purgelink" {{#if: {{{2|}}} | data-pagename="{{{2}}}" }}>{{выполнить скрипт|purgeLink}}[[Special:Purge/{{#if: {{{2|}}} | {{{2}}} | {{FULLPAGENAME}} }}|{{#if: {{{1|}}} | {{{1}}} | Очистить кэш }}]]</span>{{#ifeq: {{NAMESPACE}}{{{nocat|}}}
| {{ns:10}} <!-- Шаблон -->
| {{очищать кэш|ежедневно}}
}}<noinclude>{{doc}}</noinclude>
be6695060ca61d2125386d02d3a19109c0e7c27b
Модуль:Yesno
828
127
296
2024-03-30T22:30:54Z
ruwiki>Stjn
0
кириллическая у из-за невозможности различить от латинской
Scribunto
text/plain
-- Function allowing for consistent treatment of boolean-like wikitext input.
-- It works similarly to the template {{yesno}}.
return function (val, default)
-- If your wiki uses non-ascii characters for any of "yes", "no", etc., you
-- should replace "val:lower()" with "mw.ustring.lower(val)" in the
-- following line.
val = type(val) == 'string' and val:lower() or val
if val == nil then
return nil
elseif val == true
or val == 'yes'
or val == 'y'
or val == 'true'
or val == 't'
or val == 'да'
or val == 'д'
-- кириллица
or val == 'у'
or val == '+'
or tonumber(val) == 1
then
return true
elseif val == false
or val == 'no'
or val == 'n'
or val == 'false'
or val == 'f'
or val == 'нет'
or val == 'н'
or val == '-'
or tonumber(val) == 0
then
return false
else
return default
end
end
ae94e12a838e770797317ed07b57b330ffeb7658
Шаблон:Yesno-yes
10
153
348
2024-04-05T13:04:36Z
ruwiki>Stjn
0
подстановка
wikitext
text/x-wiki
{{safesubst:<noinclude />yesno|{{{1}}}|yes={{{yes|yes}}}|no={{{no|no}}}|blank={{{blank|yes}}}|¬={{{¬|yes}}}|def={{{def|yes}}}}}<noinclude>
{{doc}}
</noinclude>
3792ff694708f98102e3a6d556abe73bedc29069
Шаблон:Выполнить скрипт
10
182
406
2024-04-07T13:34:28Z
ruwiki>Stjn
0
отключение старой схемы
wikitext
text/x-wiki
{{#switch: {{{1|}}}
| =
| mainPage = [[Категория:Википедия:Заглавная страница|{{NAMESPACENUMBER}}]]
| #default = {{#ifexist: Категория:Википедия:Страницы с гаджетом по требованию {{{1}}} | [[Категория:Википедия:Страницы с гаджетом по требованию {{{1}}}|{{NAMESPACENUMBER}}]] }}
}}<noinclude>
{{doc}}
</noinclude>
6979ea0342067dc76b9adcb9a5e072207c2c5a63
Шаблон:СИШ
10
207
462
2024-04-07T23:07:09Z
ruwiki>Stjn
0
режет глаз
wikitext
text/x-wiki
<noinclude>{{к объединению|2020-11-10|Шаблон:High-use}}
</noinclude>{{ombox
|type = notice
|image = [[Файл:Stalewarning.svg|40px|alt=Время]]
|text = '''Внимание! Это один из [[Special:MostLinkedTemplates|самых используемых {{#ifeq: {{NAMESPACENUMBER}} | 828 | модулей | шаблонов }}]].'''
|text-small = Каждое его изменение создаёт [[mw:Manual:Job queue/ru|дополнительную нагрузку]] на сервера проекта. Пожалуйста, убедитесь в адекватности и правильности ваших изменений, проверьте их на тестовых страницах.<br>[https://templatecount.toolforge.org/index.php?lang=ru&name={{PAGENAMEE}}&namespace={{NAMESPACENUMBER}} Узнать число включений].
}}<includeonly>{{no-doc|nocat={{{nocat|}}}|[[Категория:Шаблоны:С более чем 100 тысячами использований]]}}</includeonly><noinclude>
{{doc}}
</noinclude>
013201ef8d4ba8e3d1eb0dbba9c331a3d4ae519b
Шаблон:High-use
10
220
488
2024-04-08T04:49:44Z
ruwiki>MBH
0
[[у:Землеройкин/remove.js|Удалятор]]: номинация [[ВП:к удалению/8 апреля 2024#Шаблон:High-use]]
wikitext
text/x-wiki
<noinclude>{{к удалению|2024-04-08}}
</noinclude><noinclude>{{к объединению|2020-11-10|Шаблон:СИШ}}</noinclude>{{ombox
| type = style
| image = [[File:OOjs UI icon alert-yellow.svg|40px|alt=|link=]]
| text =
Этот {{#switch: {{NAMESPACE}} | Модуль = модуль | #default = шаблон }} используется на многих страницах, поэтому изменения в нём будут заметны многим. Пожалуйста, протестируйте любые изменения в песочнице или на вашей личной подстранице. Рассмотрите возможность обсуждения изменений на [[{{#switch: {{SUBPAGENAME}}
| doc | sandbox = {{TALKSPACE}}:{{BASEPAGENAME}}
| #default = {{TALKPAGENAME}}
}}|странице обсуждения]] или [[ВП:Форум|форуме]] перед их внесением.<br>[https://templatecount.toolforge.org/index.php?lang=ru&name={{PAGENAMEE}}&namespace={{NAMESPACENUMBER}} Узнать число включений].
}}<includeonly>{{no-doc|nocat={{{nocat|}}}| [[Категория:Шаблоны:Критические]] }}</includeonly><noinclude>{{doc}}</noinclude>
ded73fd2acfa6bc0f9f309d7d66181c33a520198
Модуль:UnitTests
828
206
460
2024-04-08T16:59:24Z
ruwiki>Vavilexxx
0
уточнение
Scribunto
text/plain
-- Модуль основан на коде модуля [[:en:Module:UnitTests|Module:UnitTests]] англоязычного раздела Википедии.
-- UnitTester provides unit testing for other Lua scripts. For details see [[Wikipedia:Lua#Unit_testing]].
-- For user documentation see talk page.
local UnitTester = {}
local frame, tick, cross, should_highlight
local result_table_header = '{|class="wikitable unit-tests-result"\n|+ %s\n' ..
'! scope="col" | \n' ..
'! scope="col" | Тест\n' ..
'! scope="col" | Ожидаемое значение\n' ..
'! scope="col" | Фактическое значение '
local result_table_live_sandbox_header = '{|class="wikitable unit-tests-result"\n|+ %s\n' ..
'! scope="col" | \n' ..
'! scope="col" | Тест\n' ..
'! scope="col" | Фактическое значение\n' ..
'! scope="col" | Песочница\n' ..
'! scope="col" | Ожидаемое значение'
local result_table = { n = 0 }
local result_table_mt = {
insert = function (self, ...)
local n = self.n
for i = 1, select('#', ...) do
local val = select(i, ...)
if val ~= nil then
n = n + 1
self[n] = val
end
end
self.n = n
end,
insert_format = function (self, ...)
self:insert(string.format(...))
end,
concat = table.concat
}
result_table_mt.__index = result_table_mt
setmetatable(result_table, result_table_mt)
local num_failures = 0
local num_runs = 0
local function first_difference(s1, s2)
s1, s2 = tostring(s1), tostring(s2)
if s1 == s2 then return '' end
local max = math.min(#s1, #s2)
for i = 1, max do
if s1:sub(i,i) ~= s2:sub(i,i) then return i end
end
return max + 1
end
local function return_varargs(...)
return ...
end
function UnitTester:calculate_output(text, expected, actual, options)
-- Set up some variables for throughout for ease
num_runs = num_runs + 1
local options = options or {}
-- Fix any stripmarkers if asked to do so to prevent incorrect fails
local compared_expected = expected
local compared_actual = actual
if options.templatestyles then
local pattern = '(\127[^\127]*UNIQ%-%-templatestyles%-)(%x+)(%-QINU[^\127]*\127)'
local _, expected_stripmarker_id = compared_expected:match(pattern) -- when module rendering has templatestyles strip markers, use ID from expected to prevent false test fail
if expected_stripmarker_id then
compared_actual = compared_actual:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3') -- replace actual id with expected id; ignore second capture in pattern
compared_expected = compared_expected:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3') -- account for other strip markers
end
end
if options.stripmarker then
local pattern = '(\127[^\127]*UNIQ%-%-%l+%-)(%x+)(%-%-?QINU[^\127]*\127)'
local _, expected_stripmarker_id = compared_expected:match(pattern)
if expected_stripmarker_id then
compared_actual = compared_actual:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3')
compared_expected = compared_expected:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3')
end
end
-- Perform the comparison
local success = compared_actual == compared_expected
if not success then
num_failures = num_failures + 1
end
-- Sort the wikitext for displaying the results
if options.combined then
-- We need 2 rows available for the expected and actual columns
-- Top one is parsed, bottom is unparsed
local differs_at = self.differs_at and (' \n| rowspan=2|' .. first_difference(compared_expected, compared_actual)) or ''
-- Local copies of tick/cross to allow for highlighting
local highlight = (should_highlight and not success and 'style="background:#fc0;" ') or ''
result_table:insert( -- Start output
'| ', highlight, 'rowspan=2|', success and tick or cross, -- Tick/Cross (2 rows)
' \n| rowspan=2|', mw.text.nowiki(text), ' \n| ', -- Text used for the test (2 rows)
expected, ' \n| ', actual, -- The parsed outputs (in the 1st row)
differs_at, ' \n|-\n| ', -- Where any relevant difference was (2 rows)
mw.text.nowiki(expected), ' \n| ', mw.text.nowiki(actual), -- The unparsed outputs (in the 2nd row)
'\n|-\n' -- End output
)
else
-- Display normally with whichever option was preferred (nowiki/parsed)
local differs_at = self.differs_at and (' \n| ' .. first_difference(compared_expected, compared_actual)) or ''
local formatting = options.nowiki and mw.text.nowiki or return_varargs
local highlight = (should_highlight and not success and 'style="background:#fc0;"|') or ''
result_table:insert( -- Start output
'| ', highlight, success and tick or cross, -- Tick/Cross
' \n| ', mw.text.nowiki(text), ' \n| ', -- Text used for the test
formatting(expected), ' \n| ', formatting(actual), -- The formatted outputs
differs_at, -- Where any relevant difference was
'\n|-\n' -- End output
)
end
end
function UnitTester:preprocess_equals(text, expected, options)
local actual = frame:preprocess(text)
self:calculate_output(text, expected, actual, options)
end
function UnitTester:preprocess_equals_many(prefix, suffix, cases, options)
for _, case in ipairs(cases) do
self:preprocess_equals(prefix .. case[1] .. suffix, case[2], options)
end
end
function UnitTester:preprocess_equals_preprocess(text1, text2, options)
local actual = frame:preprocess(text1)
local expected = frame:preprocess(text2)
self:calculate_output(text1, expected, actual, options)
end
function UnitTester:preprocess_equals_compare(live, sandbox, expected, options)
local live_text = frame:preprocess(live)
local sandbox_text = frame:preprocess(sandbox)
local highlight_live = false
local highlight_sandbox = false
num_runs = num_runs + 1
if live_text == expected and sandbox_text == expected then
result_table:insert('| ', tick)
else
result_table:insert('| ', cross)
num_failures = num_failures + 1
if live_text ~= expected then
highlight_live = true
end
if sandbox_text ~= expected then
highlight_sandbox = true
end
end
local formatting = (options and options.nowiki and mw.text.nowiki) or return_varargs
local differs_at = self.differs_at and (' \n| ' .. first_difference(expected, live_text) or first_difference(expected, sandbox_text)) or ''
result_table:insert(
' \n| ',
mw.text.nowiki(live),
should_highlight and highlight_live and ' \n|style="background: #fc0;"| ' or ' \n| ',
formatting(live_text),
should_highlight and highlight_sandbox and ' \n|style="background: #fc0;"| ' or ' \n| ',
formatting(sandbox_text),
' \n| ',
formatting(expected),
differs_at,
"\n|-\n"
)
end
function UnitTester:preprocess_equals_preprocess_many(prefix1, suffix1, prefix2, suffix2, cases, options)
for _, case in ipairs(cases) do
self:preprocess_equals_preprocess(prefix1 .. case[1] .. suffix1, prefix2 .. (case[2] and case[2] or case[1]) .. suffix2, options)
end
end
function UnitTester:preprocess_equals_sandbox_many(module, function_name, cases, options)
for _, case in ipairs(cases) do
local live = module .. "|" .. function_name .. "|" .. case[1] .. "}}"
local sandbox = module .. "/песочница|" .. function_name .. "|" .. case[1] .. "}}"
self:preprocess_equals_compare(live, sandbox, case[2], options)
end
end
function UnitTester:equals(name, actual, expected, options)
num_runs = num_runs + 1
if actual == expected then
result_table:insert('| ', tick)
else
result_table:insert('| ', cross)
num_failures = num_failures + 1
end
local formatting = (options and options.nowiki and mw.text.nowiki) or return_varargs
local differs_at = self.differs_at and (' \n| ' .. first_difference(expected, actual)) or ''
local display = options and options.display or return_varargs
result_table:insert(' \n| ', name, ' \n| ',
formatting(tostring(display(expected))), ' \n| ',
formatting(tostring(display(actual))), differs_at, "\n|-\n")
end
local function deep_compare(t1, t2, ignore_mt)
local ty1 = type(t1)
local ty2 = type(t2)
if ty1 ~= ty2 then return false end
if ty1 ~= 'table' and ty2 ~= 'table' then return t1 == t2 end
local mt = getmetatable(t1)
if not ignore_mt and mt and mt.__eq then return t1 == t2 end
for k1, v1 in pairs(t1) do
local v2 = t2[k1]
if v2 == nil or not deep_compare(v1, v2) then return false end
end
for k2, v2 in pairs(t2) do
local v1 = t1[k2]
if v1 == nil or not deep_compare(v1, v2) then return false end
end
return true
end
local function val_to_str(obj)
local function table_key_to_str(k)
if type(k) == 'string' and mw.ustring.match(k, '^[_%a][_%a%d]*$') then
return k
else
return '[' .. val_to_str(k) .. ']'
end
end
if type(obj) == "string" then
obj = mw.ustring.gsub(obj, "\n", "\\n")
if mw.ustring.match(mw.ustring.gsub(obj, '[^\'"]', ''), '^"+$') then
return "'" .. obj .. "'"
end
return '"' .. mw.ustring.gsub(obj, '"', '\\"' ) .. '"'
elseif type(obj) == "table" then
local result, checked = {}, {}
for k, v in ipairs(obj) do
table.insert(result, val_to_str(v))
checked[k] = true
end
for k, v in pairs(obj) do
if not checked[k] then
table.insert(result, table_key_to_str(k) .. '=' .. val_to_str(v))
end
end
return '{' .. table.concat(result, ',') .. '}'
else
return tostring(obj)
end
end
function UnitTester:equals_deep(name, actual, expected, options)
num_runs = num_runs + 1
if deep_compare(actual, expected) then
result_table:insert('| ', tick)
else
result_table:insert('| ', cross)
num_failures = num_failures + 1
end
local formatting = (options and options.nowiki and mw.text.nowiki) or return_varargs
local actual_str = val_to_str(actual)
local expected_str = val_to_str(expected)
local differs_at = self.differs_at and (' \n| ' .. first_difference(expected_str, actual_str)) or ''
result_table:insert(' \n| ', name, ' \n| ', formatting(expected_str),
' \n| ', formatting(actual_str), differs_at, "\n|-\n")
end
function UnitTester:iterate(examples, func)
require 'libraryUtil'.checkType('iterate', 1, examples, 'table')
if type(func) == 'string' then
func = self[func]
elseif type(func) ~= 'function' then
error(("bad argument #2 to 'iterate' (expected function or string, got %s)")
:format(type(func)), 2)
end
for i, example in ipairs(examples) do
if type(example) == 'table' then
func(self, unpack(example))
elseif type(example) == 'string' then
self:heading(example)
else
error(('bad example #%d (expected table, got %s)')
:format(i, type(example)), 2)
end
end
end
function UnitTester:heading(text)
result_table:insert_format(' ! colspan="%u" style="text-align: left" | %s \n |- \n ',
self.columns, text)
end
function UnitTester:run(frame_arg)
frame = frame_arg
self.frame = frame
self.differs_at = frame.args['differs_at']
tick = frame:preprocess('{{Tick}}')
cross = frame:preprocess('{{Cross}}')
local table_header = result_table_header
if frame.args['live_sandbox'] then
table_header = result_table_live_sandbox_header
end
if frame.args.highlight then
should_highlight = true
end
self.columns = 4
if self.differs_at then
table_header = table_header .. '\n! scope="col" title="Различается на символе" | Разл. на'
self.columns = self.columns + 1
end
-- Sort results into alphabetical order.
local self_sorted = {}
for key, _ in pairs(self) do
if key:find('^test') then
table.insert(self_sorted, key)
end
end
table.sort(self_sorted)
-- Add results to the results table.
for _, value in ipairs(self_sorted) do
result_table:insert_format(table_header .. "\n|-\n", value)
self[value](self)
result_table:insert("|}\n")
end
local cat_failures = '[[Категория:Модули:Страницы с проваленными юнит-тестами]]'
return (num_runs == 0 and "<b>Нет тестов для запуска.</b>"
or num_failures == 0 and "<b style=\"color:#008000\">Все тесты успешно пройдены: " .. num_runs .. "</b>"
or "<b style=\"color:#800000\">" .. num_failures .. " тестов из " .. num_runs .. " провалено.</b>" .. cat_failures
) .. "\n\n" .. frame:preprocess(result_table:concat())
end
function UnitTester:new()
local o = {}
setmetatable(o, self)
self.__index = self
return o
end
local p = UnitTester:new()
function p.run_tests(frame) return p:run(frame) end
return p
f88824c8866c120062332f00624435f8323f488b
Шаблон:Старый-новый стиль,примечание
10
302
765
2024-04-13T19:25:38Z
ruwiki>Mikhail Ryazanov
0
[[Календарная дата#Форматы записи даты]], стилевые правки
wikitext
text/x-wiki
В случае, если дата рождения/смерти в источниках приведена по [[Юлианский календарь|старому стилю]], рекомендуется указывать её по новому стилю, а после указать в скобках отличающуюся часть даты по старому стилю. Например,
* «13.05.1801 (1)» будет отображено как [[13 мая|1 (13) мая]] [[1801 год|1801]];
* «12.06.1801 (31.05)» будет отображено как 31 мая ([[12 июня]]) [[1801 год|1801]];
* «12.01.1802 (31.12.1801)» будет отображено как 31 декабря 1801 ([[12 января]] [[1802 год|1802]]).
При этом в статью будут автоматически подставлены категории даты рождения/смерти по ''новому'' стилю. Учтите, что разница между датами нового и старого стиля составляет 13 дней в XX и XXI веках, 12 дней в XIX веке, 11 дней в XVIII веке, 10 дней в XVII и XVI веках (начиная с 5 (15) октября 1582 года).<noinclude>{{doc-inline}}Шаблон предназначен для подстановки в качестве примечания к полям «дата рождения», «дата смерти» для страниц документации шаблонов-карточек типа «Персона».
Параметров не принимает.
Вызов: {{tl|Старый-новый стиль,примечание}} {{doc-end}} [[Категория:Википедия:Шаблоны, встраиваемые в шаблоны-карточки:Личности]]
</noinclude>
7f8754eb5c2401671df545a1cd8b315f66f86463
Шаблон:Replace
10
145
332
2024-04-14T07:24:11Z
ruwiki>Stjn
0
обновление аналогично английскому шаблону
wikitext
text/x-wiki
{{safesubst:<noinclude />#invoke:String|replace|source={{{1}}}|{{{2}}}|{{{3}}}|plain={{{plain|true}}}|count={{{count|}}}}}<noinclude>
{{doc}}
</noinclude>
7752c3c70ae8c46a89a0808aa282956866dbba5b
Шаблон:Начало скрытого блока
10
196
438
2024-04-15T20:10:25Z
ruwiki>Stjn
0
см. [[phab:T185674#9715417]]
wikitext
text/x-wiki
<includeonly><templatestyles src="Шаблон:Скрытый блок/styles.css" /><!--
--><div class="mw-collapsible {{#switch: {{{состояние|{{{state|}}}}}} | expanded | autocollapse = {{{состояние|{{{state|}}}}}} | mw-collapsed }} ts-Скрытый_блок ts-Скрытый_блок-{{#switch: {{{тип|{{{type|}}}}}} | gray | transparent = {{{тип|{{{type|}}}}}} | gray }} ts-Скрытый_блок-{{#switch: {{{Ссылка|{{{ссылка|}}}}}} | none = none | right | left = {{{Ссылка|{{{ссылка|}}}}}} | right }}HideLink {{{класс_тела|{{{класс тела|}}}}}}" style="{{ifempty |до = border: | {{{Рамка|{{{border|{{{рамка|}}}}}}}}} |после=;}}{{{frame-style|{{{стиль_тела|{{{стиль тела|}}}}}}}}}"><!--
--><div class="ts-Скрытый_блок-title {{#switch: {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}} | none = none | left | right = ts-Скрытый_блок-title-{{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}}Title }} {{{класс_заголовка|{{{класс заголовка|}}}}}}" style="<!--
-->{{ifempty |до = background-color: | {{{Фон_заголовка|{{{bg1|{{{фон_заголовка|{{{фон заголовка|}}}}}}}}}}}} |после=;}}<!--
-->{{ifempty |до = text-align: | {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}} |после=;}}<!--
-->{{ifempty |до = font-weight: | {{{Шрифт_заголовка|{{{шрифт_заголовка|{{{шрифт заголовка|}}}}}}}}} |после=;}}<!--
-->{{ifempty |до = font-style: | {{{Наклон_заголовка|{{{наклон_заголовка|{{{наклон заголовка|}}}}}}}}} |после=;}}<!--
-->{{{Стиль_заголовка|{{{extra1|{{{стиль_заголовка|{{{стиль заголовка|}}}}}}}}}}}}"><!--
-->{{{Заголовок|{{{заголовок|{{{Заглавие|{{{заглавие|{{{Название|{{{название|{{{header|{{{title|{{{1}}}}}}}}}}}}}}}}}}}}}}}}}}}<!--
--><div class="mw-collapsible-toggle-placeholder"></div></div><!--
--><div class="mw-collapsible-content {{{класс_текста|{{{класс текста|}}}}}}" style="<!--
-->{{ifempty |до = background-color: | {{{Фон_текста|{{{bg2|{{{фон_текста|{{{фон текста|}}}}}}}}}}}} |после=;}}<!--
-->{{ifempty |до = font-weight: | {{{Шрифт_текста|{{{шрифт_текста|{{{шрифт текста|}}}}}}}}} |после=;}}<!--
-->{{ifempty |до = font-style: | {{{Наклон_текста|{{{наклон_текста|{{{наклон текста|}}}}}}}}} |после=;}}<!--
-->{{ifempty |до = text-align: | {{{Выравнивание_текста|{{{ta2|{{{выравнивание_текста|{{{выравнивание текста|}}}}}}}}}}}} |после=;}}<!--
-->{{{Стиль_текста|{{{extra2|{{{стиль_текста|{{{стиль текста|}}}}}}}}}}}}"><!--
--></includeonly><noinclude>
{{doc}}
</noinclude>
3b96bb802b522e629c41cddc5d44dfb2a9eb462a
Модуль:Wikidata/config
828
142
326
2024-04-18T14:43:27Z
ruwiki>Stjn
0
[[ВП:Откат|откат]] правок [[Special:Contribs/Stjn|Stjn]] ([[UT:Stjn|обс.]]) к версии Ghuron
Scribunto
text/plain
-- Property configuration for Wikidata module
return {
global = {
separator = ', ',
conjunction = ' и ',
},
presets = {
['catonly'] = {
datatype = 'wikibase-item',
conjunction = '',
invisible = true,
['value-module'] = 'Wikidata/item',
['value-function'] = 'formatCategoryOnly',
references = '',
category = 'P910',
},
['country'] = {
datatype = 'wikibase-item',
['claim-module'] = 'Wikidata/Places',
['claim-function'] = 'formatCountryClaimWithFlag',
before = '<ul><li>',
separator = '</li><li>',
conjunction = '</li><li>',
after = '</li></ul>',
},
['from-to'] = {
datatype = 'time',
['property-module'] = 'Wikidata/date',
['property-function'] = 'formatDateIntervalProperty',
},
['link'] = {
['value-module'] = 'Wikidata/link',
['value-function'] = 'fromModule',
},
['list'] = {
before = '<ul><li>',
separator = '</li><li>',
conjunction = '</li><li>',
after = '</li></ul>',
},
['name'] = {
datatype = 'monolingualtext',
monolingualLangTemplate = 'lang',
separator = '<br>',
conjunction = '<br>',
},
['place'] = {
datatype = 'wikibase-item',
['claim-module'] = 'Wikidata/Places',
['claim-function'] = 'formatPlaceWithQualifiers',
before = '<ul><li>',
separator = '</li><li>',
conjunction = '</li><li>',
after = '</li></ul>',
},
['quantity (date)'] = {
datatype = 'quantity',
before = '<ul><li>',
separator = '</li><li>',
conjunction = '</li><li>',
after = '</li></ul>',
qualifier = 'P585',
},
},
datatypes = {
commonsMedia = {
limit = 1,
references = false,
size = '274x400px',
separator = '<br>',
conjunction = '<br>',
somevalue = '',
['value-module'] = 'Wikidata/media',
['value-function'] = 'formatCommonsMediaValue',
},
['external-id'] = {
references = false,
},
['globe-coordinate'] = {
limit = 1,
references = false,
},
url = {
separator = '<br>',
conjunction = '<br>',
references = false,
['value-module'] = 'Wikidata/url',
['value-function'] = 'formatUrlValue',
},
quantity = {
siConversion = true
}
},
properties = {
P6 = { datatype = 'wikibase-item', },
P17 = {
preset = 'country',
},
P18 = {
datatype = 'commonsMedia',
fixdouble = true,
},
P19 = {
preset = 'place',
separator = ',</li><li>',
conjunction = ' или </li><li>',
},
P20 = {
preset = 'place',
separator = ',</li><li>',
conjunction = ' или </li><li>',
},
P22 = {
datatype = 'wikibase-item',
conjunction = ' или '
},
P25 = {
datatype = 'wikibase-item',
conjunction = ' или '
},
P26 = { datatype = 'wikibase-item', },
P27 = {
preset = 'country',
},
P31 = {
datatype = 'wikibase-item',
references = false,
},
P37 = { datatype = 'wikibase-item', },
P39 = {
datatype = 'wikibase-item',
['claim-module'] = 'Wikidata/positions',
['claim-function'] = 'formatPositionClaim',
separator = '',
conjunction = '',
allowTables = true,
},
P40 = { datatype = 'wikibase-item', },
P41 = {
datatype = 'commonsMedia',
size = '150x200px',
},
P53 = {
datatype = 'wikibase-item',
category = 'P910',
},
P54 = {
category = 'P6112',
},
P57 = {
datatype = 'wikibase-item',
preset = 'list',
},
P58 = {
datatype = 'wikibase-item',
preset = 'list',
},
P59 = {
datatype = 'wikibase-item',
category = 'P910',
references = false,
},
P69 = {
datatype = 'wikibase-item',
preset = 'list',
category = 'P3876',
qualifier = 'P582',
},
P94 = {
datatype = 'commonsMedia',
size = '100x200px',
},
P86 = {
datatype = 'wikibase-item',
preset = 'list',
},
P101 = { datatype = 'wikibase-item', },
P102 = {
datatype = 'wikibase-item',
preset = 'list',
qualifier = 'P582',
category = 'P6365',
},
P103 = { datatype = 'wikibase-item', },
P106 = {
datatype = 'wikibase-item',
['claim-module'] = 'Wikidata/item',
['claim-function'] = 'formatEntityWithGenderClaim',
conjunction = ', ',
},
P108 = {
datatype = 'wikibase-item',
preset = 'list',
category = 'P4195',
},
P109 = {
datatype = 'commonsMedia',
size = '150x150px',
alt = 'Изображение автографа',
},
P117 = {
datatype = 'commonsMedia',
size = '290x300px',
alt = 'Изображение химической структуры',
},
P119 = {
preset = 'place',
thisLocationOnly = 'true',
},
P131 = { datatype = 'wikibase-item', },
P140 = {
datatype = 'wikibase-item',
},
P154 = {
size = '220x80px',
alt = 'Изображение логотипа',
},
P159 = {
preset = 'place',
},
P161 = {
preset = 'list',
},
P162 = {
preset = 'list',
},
P163 = { datatype = 'wikibase-item', },
P166 = {
datatype = 'wikibase-item',
['property-module'] = 'Wikidata/Medals',
['property-function'] = 'formatProperty',
['value-module'] = 'Wikidata/Medals',
['value-function'] = 'formatValue',
before = '<div style="text-align:justify">',
after = '</div>',
separator = ' ',
conjunction = ' ',
references = false,
allowTables = true,
},
P190 = { datatype = 'wikibase-item', },
P212 = {
preset = 'link',
},
P225 = {
preset = 'list',
['claim-module'] = 'Wikidata/Biology',
['claim-function'] = 'formatTaxonNameClaim',
},
P237 = { datatype = 'wikibase-item', },
P241 = { datatype = 'wikibase-item', },
P242 = {
datatype = 'commonsMedia',
size = '300x300px',
},
P247 = {
formatter = 'https://nssdc.gsfc.nasa.gov/nmc/spacecraft/display.action?id=$1',
},
P267 = {
preset = 'link',
},
P276 = {
preset = 'place',
},
P281 = { datatype = 'string', },
P286 = {
preset = 'list',
},
P296 = {
formatter = 'http://osm.sbin.ru/esr/esr:$1',
},
P301 = {
rawArticle = true,
},
P344 = {
preset = 'list',
},
P345 = {
preset = 'link',
},
P348 = {
preset = 'list',
['property-module'] = 'Wikidata/Software',
['property-function'] = 'formatVersionProperty',
},
P361 = { datatype = 'wikibase-item', },
P373 = {
datatype = 'string',
['value-module'] = 'Wikidata/media',
['value-function'] = 'formatCommonsCategory',
limit = 1,
},
P374 = { datatype = 'external-id', },
P395 = { datatype = 'string', },
P407 = { datatype = 'wikibase-item', },
P410 = { datatype = 'wikibase-item', },
P412 = {
datatype = 'wikibase-item',
category = 'P910',
},
P413 = {
datatype = 'wikibase-item',
['claim-module'] = 'Wikidata/item',
['claim-function'] = 'formatEntityWithGenderClaim',
conjunction = ', ',
category = 'P910',
},
P414 = {
['claim-module'] = 'Wikidata/item',
['claim-function'] = 'applyDefaultTemplate',
},
P421 = { datatype = 'wikibase-item', },
P473 = { datatype = 'string', },
P495 = {
preset = 'country',
},
P505 = {
preset = 'list',
},
P512 = {
datatype = 'wikibase-item',
['property-module'] = 'Wikidata/P512',
['property-function'] = 'formatAcademicDegree',
},
P527 = {
preset = 'list',
},
P528 = {
references = false,
qualifier = 'P972',
},
P551 = {
preset = 'place',
},
P569 = {
datatype = 'time',
['claim-module'] = 'Wikidata/date',
['claim-function'] = 'formatDateOfBirthClaim',
},
P570 = {
datatype = 'time',
['claim-module'] = 'Wikidata/date',
['claim-function'] = 'formatDateOfDeathClaim',
},
P571 = { datatype = 'time', },
P576 = { datatype = 'time', },
P598 = { datatype = 'wikibase-item', },
P607 = {
datatype = 'wikibase-item',
preset = 'list',
},
P625 = { datatype = 'globe-coordinate', },
P669 = {
qualifier = 'P670',
},
P685 = {
formatter = 'https://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?mode=Info&id=$1',
},
P721 = {
preset = 'link',
},
P764 = {
preset = 'link',
},
P803 = { datatype = 'wikibase-item', },
P856 = { datatype = 'url', },
P881 = {
novalue = 'нет',
category = 'P910',
},
P884 = {
preset = 'link',
},
P915 = {
category = 'P1740',
},
P957 = {
preset = 'link',
},
P972 = {
preset = 'catonly',
},
P1077 = {
preset = 'link',
},
P1082 = {
preset = 'quantity (date)',
unit = 'чел.',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator'
},
P1098 = {
preset = 'quantity (date)',
unit = 'чел.',
},
P1120 = {
preset = 'quantity (date)',
unit = 'чел.',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator'
},
P1128 = {
datatype = 'quantity',
preset = 'quantity (date)',
unit = 'чел.',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator'
},
P1114 = {
datatype = 'quantity',
qualifier = 'P585',
},
P1174 = {
preset = 'quantity (date)',
unit = 'чел.',
},
P1195 = {
['value-module'] = 'Wikidata/Software',
['value-function'] = 'formatExtension',
conjunction = ' или ',
},
P1215 = {
datatype = 'quantity',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatVisualMagnitude'
},
P1246 = {
preset = 'link',
},
P1249 = { datatype = 'time', },
P1352 = { preset = 'quantity (date)', },
P1376 = { datatype = 'wikibase-item', },
P1402 = {
preset = 'link',
},
P1448 = {
preset = 'name',
},
P1458 = {
datatype = 'quantity',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatColorIndex'
},
P1464 = { datatype = 'wikibase-item', },
P1476 = {
preset = 'name',
},
P1477 = {
preset = 'name',
},
P1532 = {
preset = 'country',
rank = '[rank:normal, rank:preferred]',
},
P1543 = {
datatype = 'commonsMedia',
},
P1559 = {
preset = 'name',
},
P1603 = {
preset = 'quantity (date)',
unit = 'чел.',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator'
},
P1621 = {
size = '300x300px',
},
P1692 = {
preset = 'link',
},
P1705 = {
preset = 'name',
},
P1753 = {
rowArticle = true,
},
P1809 = {
preset = 'list',
},
P1846 = {
datatype = 'commonsMedia',
fixdouble = true,
},
P2031 = {
preset = 'from-to',
to = 'P2032',
within = 'P570',
},
P2043 = {
preset = 'quantity (date)',
},
P2044 = { datatype = 'quantity', },
P2046 = {
preset = 'quantity (date)',
siConversion = false,
},
P2047 = {
siConversion = false,
},
P2048 = {
conjunction = ' или ',
},
P2060 = {
siConversion = false,
},
P2097 = {
siConversion = false,
},
P2120 = {
siConversion = false,
},
P2137 = {
preset = 'quantity (date)',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator',
countByThousands = true,
},
P2139 = {
preset = 'quantity (date)',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator',
countByThousands = true,
},
P2146 = {
siConversion = false,
},
P2214 = {
siConversion = false
},
P2226 = {
preset = 'quantity (date)',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator',
countByThousands = true,
},
P2257 = {
siConversion = false
},
P2260 = {
siConversion = false
},
P2295 = {
preset = 'quantity (date)',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator',
countByThousands = true,
},
P2324 = {
datatype = 'quantity',
preset = 'quantity (date)',
unit = 'чел.'
},
P2403 = {
preset = 'quantity (date)',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator',
countByThousands = true,
},
P2425 = {
alt = 'Изображение орденской планки',
},
P2583 = {
siConversion = false,
},
P2597 = {
preset = 'catonly',
},
P2650 = { datatype = 'wikibase-item', },
P2789 = {
preset = 'list',
},
P2896 = {
siConversion = false,
},
P2910 = {
size = '100x80px',
},
P3083 = {
formatter = 'http://simbad.u-strasbg.fr/simbad/sim-id?Ident=$1',
},
P3086 = {
siConversion = false,
},
P3362 = {
preset = 'quantity (date)',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator',
countByThousands = true,
},
P4614 = {
category = 'P1200',
},
P5348 = {
siConversion = false,
},
P6257 = {
['value-module'] = 'Wikidata/number',
['value-function'] = 'formatRA',
},
P6258 = {
['value-module'] = 'Wikidata/number',
['value-function'] = 'formatDMS',
},
P6259 = {
['references'] = false,
},
P7584 = {
siConversion = false,
},
P8010 = {
datatype = 'quantity',
preset = 'quantity (date)',
unit = 'чел.',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator'
},
P8224 = {
alt = 'Изображение молекулярной модели',
},
},
categories = {
['links-to-entities-with-missing-label'] = 'Википедия:Статьи со ссылками на элементы Викиданных без подписи',
['links-to-entities-with-wikibase-error'] = 'Википедия:Страницы с ошибками скриптов, использующих Викиданные',
['links-to-entities-with-missing-local-language-label'] = 'Википедия:Статьи со ссылками на элементы Викиданных без русской подписи',
['media-contains-local-caption'] = 'Википедия:Локальная подпись у изображения из Викиданных',
['media-contains-markup'] = 'Википедия:Статьи с вики-разметкой в изображении карточки',
['media-contains-local-double'] = 'Википедия:Изображение в статье дублирует изображение в карточке',
['value-contains-table'] = 'Википедия:Статьи с табличной вставкой в карточке',
},
errors = {
['property-param-not-provided'] = 'Не дан параметр свойства',
['entity-not-found'] = 'Сущность не найдена.',
['unknown-claim-type'] = 'Неизвестный тип заявления.',
['unknown-snak-type'] = 'Неизвестный тип снэка.',
['unknown-datavalue-type'] = 'Неизвестный тип значения данных.',
['unknown-entity-type'] = 'Неизвестный тип сущности.',
['unknown-property-module'] = 'Вы должны установить и property-module, и property-function.',
['unknown-claim-module'] = 'Вы должны установить и claim-module, и claim-function.',
['unknown-value-module'] = 'Вы должны установить и value-module, и value-function.',
['property-module-not-found'] = 'Модуль для отображения свойства не найден',
['property-function-not-found'] = 'Функция для отображения свойства не найдена',
['claim-module-not-found'] = 'Модуль для отображения утверждения не найден.',
['claim-function-not-found'] = 'Функция для отображения утверждения не найдена.',
['value-module-not-found'] = 'Модуль для отображения значения не найден.',
['value-function-not-found'] = 'Функция для отображения значения не найдена.',
},
i18n = {
somevalue = "''неизвестно''",
novalue = '',
-- Обстоятельства источника
Q5727902 = 'около ',
Q18122778 = '<span style="border-bottom: 1px dotted; cursor: help;" title="предположительно">предп.</span> ',
Q30230067 = 'возможно ',
Q52834024 = '<span style="border-bottom: 1px dotted; cursor: help;" title="менее чем"><</span> ',
Q54418095 = '<span style="border-bottom: 1px dotted; cursor: help;" title="более чем">></span> ',
thousandPowers = {'', ' тыс.', ' млн', ' млрд', ' трлн'},
},
deprecatedSources = {
Q355 = true, -- Facebook
Q36578 = true, -- Gemeinsame Normdatei
Q63056 = true, -- Find a Grave
Q212256 = true, -- АиФ
Q504063 = true, -- Discogs
Q523660 = true, -- International Music Score Library Project by https://ru.wikipedia.org/?diff=107090748
Q1798125 = true, -- LIBRIS
Q2621214 = true, -- Geni
Q15222191 = true, -- BNF
Q15241312 = true, -- Freebase
Q19938912 = true, -- BNF
Q21697707 = true, -- Хайазг
Q25328680 = true, -- Prabook
Q29861311 = true, -- SNAC
Q86999151 = true, -- WeChangEd
},
};
b786cd0414ef1bee304179c30b5daff1eda5baf8
Шаблон:Wikidata gender switch
10
273
707
2024-04-28T17:08:48Z
ruwiki>Dima st bk
0
+ lc по запросу на СО
wikitext
text/x-wiki
{{#switch: {{wikidata|p21|{{lc:{{delink|{{{1|}}}}}}}|plain=true|from={{{from|}}}}}
| 1 | f | fem | female | feminine | ж | жен | женский | женский пол | транс-женщина | Q6581072 | Q1052281 | Q43445 = {{{2}}}
| m | male | masculine | м | муж | мужской | мужской пол | транс-мужчина | Q6581097 | Q2449503 | Q44148 = {{{3}}}
| #default = {{#if:{{{4|}}}|{{{4}}}|{{{3}}}}}
}}<noinclude>
{{doc}}
</noinclude>
24ccdd5a8702a7028386e9b887d3acf1b5f81c34
Модуль:Citation/CS1
828
78
128
2024-04-28T20:37:46Z
ruwiki>Wikisaurus
0
[[Обсуждение Википедии:Шаблоны цитирования CS1/2#Обновление от 27 марта 2024]]
Scribunto
text/plain
require ('strict');
--[[--------------------------< F O R W A R D D E C L A R A T I O N S >--------------------------------------
each of these counts against the Lua upvalue limit
]]
local validation; -- functions in Module:Citation/CS1/Date_validation
local utilities; -- functions in Module:Citation/CS1/Utilities
local z = {}; -- table of tables in Module:Citation/CS1/Utilities
local identifiers; -- functions and tables in Module:Citation/CS1/Identifiers
local metadata; -- functions in Module:Citation/CS1/COinS
local cfg = {}; -- table of configuration tables that are defined in Module:Citation/CS1/Configuration
local whitelist = {}; -- table of tables listing valid template parameter names; defined in Module:Citation/CS1/Whitelist
local boxDate = require('Module:Calendar').bxDate; -- РУВИКИ: все даты делаем человекочитаемыми
--[[------------------< P A G E S C O P E V A R I A B L E S >---------------
declare variables here that have page-wide scope that are not brought in from
other modules; that are created here and used here
]]
local added_deprecated_cat; -- Boolean flag so that the category is added only once
local added_vanc_errs; -- Boolean flag so we only emit one Vancouver error / category
local added_generic_name_errs; -- Boolean flag so we only emit one generic name error / category and stop testing names once an error is encountered
local added_numeric_name_errs; -- Boolean flag so we only emit one numeric name error / category and stop testing names once an error is encountered
local added_numeric_name_maint; -- Boolean flag so we only emit one numeric name maint category and stop testing names once a category has been emitted
local Frame; -- holds the module's frame table
local is_preview_mode; -- true when article is in preview mode; false when using 'Preview page with this template' (previewing the module)
local is_sandbox; -- true when using sandbox modules to render citation
--[[--------------------------< F I R S T _ S E T >------------------------------------------------------------
Locates and returns the first set value in a table of values where the order established in the table,
left-to-right (or top-to-bottom), is the order in which the values are evaluated. Returns nil if none are set.
This version replaces the original 'for _, val in pairs do' and a similar version that used ipairs. With the pairs
version the order of evaluation could not be guaranteed. With the ipairs version, a nil value would terminate
the for-loop before it reached the actual end of the list.
]]
local function first_set (list, count)
local i = 1;
while i <= count do -- loop through all items in list
if utilities.is_set( list[i] ) then
return list[i]; -- return the first set list member
end
i = i + 1; -- point to next
end
end
--[[--------------------------< A D D _ V A N C _ E R R O R >----------------------------------------------------
Adds a single Vancouver system error message to the template's output regardless of how many error actually exist.
To prevent duplication, added_vanc_errs is nil until an error message is emitted.
added_vanc_errs is a Boolean declared in page scope variables above
]]
local function add_vanc_error (source, position)
if added_vanc_errs then return end
added_vanc_errs = true; -- note that we've added this category
utilities.set_message ('err_vancouver', {source, position});
end
--[[--------------------------< I S _ S C H E M E >------------------------------------------------------------
does this thing that purports to be a URI scheme seem to be a valid scheme? The scheme is checked to see if it
is in agreement with http://tools.ietf.org/html/std66#section-3.1 which says:
Scheme names consist of a sequence of characters beginning with a
letter and followed by any combination of letters, digits, plus
("+"), period ("."), or hyphen ("-").
returns true if it does, else false
]]
local function is_scheme (scheme)
return scheme and scheme:match ('^%a[%a%d%+%.%-]*:'); -- true if scheme is set and matches the pattern
end
--[=[-------------------------< I S _ D O M A I N _ N A M E >--------------------------------------------------
Does this thing that purports to be a domain name seem to be a valid domain name?
Syntax defined here: http://tools.ietf.org/html/rfc1034#section-3.5
BNF defined here: https://tools.ietf.org/html/rfc4234
Single character names are generally reserved; see https://tools.ietf.org/html/draft-ietf-dnsind-iana-dns-01#page-15;
see also [[Single-letter second-level domain]]
list of TLDs: https://www.iana.org/domains/root/db
RFC 952 (modified by RFC 1123) requires the first and last character of a hostname to be a letter or a digit. Between
the first and last characters the name may use letters, digits, and the hyphen.
Also allowed are IPv4 addresses. IPv6 not supported
domain is expected to be stripped of any path so that the last character in the last character of the TLD. tld
is two or more alpha characters. Any preceding '//' (from splitting a URL with a scheme) will be stripped
here. Perhaps not necessary but retained in case it is necessary for IPv4 dot decimal.
There are several tests:
the first character of the whole domain name including subdomains must be a letter or a digit
internationalized domain name (ASCII characters with .xn-- ASCII Compatible Encoding (ACE) prefix xn-- in the TLD) see https://tools.ietf.org/html/rfc3490
single-letter/digit second-level domains in the .org, .cash, and .today TLDs
q, x, and z SL domains in the .com TLD
i and q SL domains in the .net TLD
single-letter SL domains in the ccTLDs (where the ccTLD is two letters)
two-character SL domains in gTLDs (where the gTLD is two or more letters)
three-plus-character SL domains in gTLDs (where the gTLD is two or more letters)
IPv4 dot-decimal address format; TLD not allowed
returns true if domain appears to be a proper name and TLD or IPv4 address, else false
]=]
local function is_domain_name (domain)
if not domain then
return false; -- if not set, abandon
end
domain = domain:gsub ('^//', ''); -- strip '//' from domain name if present; done here so we only have to do it once
if not domain:match ('^[%w]') then -- first character must be letter or digit
return false;
end
if domain:match ('^%a+:') then -- hack to detect things that look like s:Page:Title where Page: is namespace at Wikisource
return false;
end
local patterns = { -- patterns that look like URLs
'%f[%w][%w][%w%-]+[%w]%.%a%a+$', -- three or more character hostname.hostname or hostname.tld
'%f[%w][%w][%w%-]+[%w]%.xn%-%-[%w]+$', -- internationalized domain name with ACE prefix
'%f[%a][qxz]%.com$', -- assigned one character .com hostname (x.com times out 2015-12-10)
'%f[%a][iq]%.net$', -- assigned one character .net hostname (q.net registered but not active 2015-12-10)
'%f[%w][%w]%.%a%a$', -- one character hostname and ccTLD (2 chars)
'%f[%w][%w][%w]%.%a%a+$', -- two character hostname and TLD
'^%d%d?%d?%.%d%d?%d?%.%d%d?%d?%.%d%d?%d?', -- IPv4 address
}
for _, pattern in ipairs (patterns) do -- loop through the patterns list
if domain:match (pattern) then
return true; -- if a match then we think that this thing that purports to be a URL is a URL
end
end
for _, d in ipairs (cfg.single_letter_2nd_lvl_domains_t) do -- look for single letter second level domain names for these top level domains
if domain:match ('%f[%w][%w]%.' .. d) then
return true
end
end
return false; -- no matches, we don't know what this thing is
end
--[[--------------------------< I S _ U R L >------------------------------------------------------------------
returns true if the scheme and domain parts of a URL appear to be a valid URL; else false.
This function is the last step in the validation process. This function is separate because there are cases that
are not covered by split_url(), for example is_parameter_ext_wikilink() which is looking for bracketted external
wikilinks.
]]
local function is_url (scheme, domain)
if utilities.is_set (scheme) then -- if scheme is set check it and domain
return is_scheme (scheme) and is_domain_name (domain);
else
return is_domain_name (domain); -- scheme not set when URL is protocol-relative
end
end
--[[--------------------------< S P L I T _ U R L >------------------------------------------------------------
Split a URL into a scheme, authority indicator, and domain.
First remove Fully Qualified Domain Name terminator (a dot following TLD) (if any) and any path(/), query(?) or fragment(#).
If protocol-relative URL, return nil scheme and domain else return nil for both scheme and domain.
When not protocol-relative, get scheme, authority indicator, and domain. If there is an authority indicator (one
or more '/' characters immediately following the scheme's colon), make sure that there are only 2.
Any URL that does not have news: scheme must have authority indicator (//). TODO: are there other common schemes
like news: that don't use authority indicator?
Strip off any port and path;
]]
local function split_url (url_str)
local scheme, authority, domain;
url_str = url_str:gsub ('([%a%d])%.?[/%?#].*$', '%1'); -- strip FQDN terminator and path(/), query(?), fragment (#) (the capture prevents false replacement of '//')
if url_str:match ('^//%S*') then -- if there is what appears to be a protocol-relative URL
domain = url_str:match ('^//(%S*)')
elseif url_str:match ('%S-:/*%S+') then -- if there is what appears to be a scheme, optional authority indicator, and domain name
scheme, authority, domain = url_str:match ('(%S-:)(/*)(%S+)'); -- extract the scheme, authority indicator, and domain portions
if utilities.is_set (authority) then
authority = authority:gsub ('//', '', 1); -- replace place 1 pair of '/' with nothing;
if utilities.is_set(authority) then -- if anything left (1 or 3+ '/' where authority should be) then
return scheme; -- return scheme only making domain nil which will cause an error message
end
else
if not scheme:match ('^news:') then -- except for news:..., MediaWiki won't link URLs that do not have authority indicator; TODO: a better way to do this test?
return scheme; -- return scheme only making domain nil which will cause an error message
end
end
domain = domain:gsub ('(%a):%d+', '%1'); -- strip port number if present
end
return scheme, domain;
end
--[[--------------------------< L I N K _ P A R A M _ O K >---------------------------------------------------
checks the content of |title-link=, |series-link=, |author-link=, etc. for properly formatted content: no wikilinks, no URLs
Link parameters are to hold the title of a Wikipedia article, so none of the WP:TITLESPECIALCHARACTERS are allowed:
# < > [ ] | { } _
except the underscore which is used as a space in wiki URLs and # which is used for section links
returns false when the value contains any of these characters.
When there are no illegal characters, this function returns TRUE if value DOES NOT appear to be a valid URL (the
|<param>-link= parameter is ok); else false when value appears to be a valid URL (the |<param>-link= parameter is NOT ok).
]]
local function link_param_ok (value)
local scheme, domain;
if value:find ('[<>%[%]|{}]') then -- if any prohibited characters
return false;
end
scheme, domain = split_url (value); -- get scheme or nil and domain or nil from URL;
return not is_url (scheme, domain); -- return true if value DOES NOT appear to be a valid URL
end
--[[--------------------------< L I N K _ T I T L E _ O K >---------------------------------------------------
Use link_param_ok() to validate |<param>-link= value and its matching |<title>= value.
|<title>= may be wiki-linked but not when |<param>-link= has a value. This function emits an error message when
that condition exists
check <link> for inter-language interwiki-link prefix. prefix must be a MediaWiki-recognized language
code and must begin with a colon.
]]
local function link_title_ok (link, lorig, title, torig)
local orig;
if utilities.is_set (link) then -- don't bother if <param>-link doesn't have a value
if not link_param_ok (link) then -- check |<param>-link= markup
orig = lorig; -- identify the failing link parameter
elseif title:find ('%[%[') then -- check |title= for wikilink markup
orig = torig; -- identify the failing |title= parameter
elseif link:match ('^%a+:') then -- if the link is what looks like an interwiki
local prefix = link:match ('^(%a+):'):lower(); -- get the interwiki prefix
if cfg.inter_wiki_map[prefix] then -- if prefix is in the map, must have preceding colon
orig = lorig; -- flag as error
end
end
end
if utilities.is_set (orig) then
link = ''; -- unset
utilities.set_message ('err_bad_paramlink', orig); -- URL or wikilink in |title= with |title-link=;
end
return link; -- link if ok, empty string else
end
--[[--------------------------< C H E C K _ U R L >------------------------------------------------------------
Determines whether a URL string appears to be valid.
First we test for space characters. If any are found, return false. Then split the URL into scheme and domain
portions, or for protocol-relative (//example.com) URLs, just the domain. Use is_url() to validate the two
portions of the URL. If both are valid, or for protocol-relative if domain is valid, return true, else false.
Because it is different from a standard URL, and because this module used external_link() to make external links
that work for standard and news: links, we validate newsgroup names here. The specification for a newsgroup name
is at https://tools.ietf.org/html/rfc5536#section-3.1.4
]]
local function check_url( url_str )
if nil == url_str:match ("^%S+$") then -- if there are any spaces in |url=value it can't be a proper URL
return false;
end
local scheme, domain;
scheme, domain = split_url (url_str); -- get scheme or nil and domain or nil from URL;
if 'news:' == scheme then -- special case for newsgroups
return domain:match('^[%a%d%+%-_]+%.[%a%d%+%-_%.]*[%a%d%+%-_]$');
end
return is_url (scheme, domain); -- return true if value appears to be a valid URL
end
--[=[-------------------------< I S _ P A R A M E T E R _ E X T _ W I K I L I N K >----------------------------
Return true if a parameter value has a string that begins and ends with square brackets [ and ] and the first
non-space characters following the opening bracket appear to be a URL. The test will also find external wikilinks
that use protocol-relative URLs. Also finds bare URLs.
The frontier pattern prevents a match on interwiki-links which are similar to scheme:path URLs. The tests that
find bracketed URLs are required because the parameters that call this test (currently |title=, |chapter=, |work=,
and |publisher=) may have wikilinks and there are articles or redirects like '//Hus' so, while uncommon, |title=[[//Hus]]
is possible as might be [[en://Hus]].
]=]
local function is_parameter_ext_wikilink (value)
local scheme, domain;
if value:match ('%f[%[]%[%a%S*:%S+.*%]') then -- if ext. wikilink with scheme and domain: [xxxx://yyyyy.zzz]
scheme, domain = split_url (value:match ('%f[%[]%[(%a%S*:%S+).*%]'));
elseif value:match ('%f[%[]%[//%S+.*%]') then -- if protocol-relative ext. wikilink: [//yyyyy.zzz]
scheme, domain = split_url (value:match ('%f[%[]%[(//%S+).*%]'));
elseif value:match ('%a%S*:%S+') then -- if bare URL with scheme; may have leading or trailing plain text
scheme, domain = split_url (value:match ('(%a%S*:%S+)'));
elseif value:match ('//%S+') then -- if protocol-relative bare URL: //yyyyy.zzz; may have leading or trailing plain text
scheme, domain = split_url (value:match ('(//%S+)')); -- what is left should be the domain
else
return false; -- didn't find anything that is obviously a URL
end
return is_url (scheme, domain); -- return true if value appears to be a valid URL
end
--[[-------------------------< C H E C K _ F O R _ U R L >-----------------------------------------------------
loop through a list of parameters and their values. Look at the value and if it has an external link, emit an error message.
]]
local function check_for_url (parameter_list, error_list)
for k, v in pairs (parameter_list) do -- for each parameter in the list
if is_parameter_ext_wikilink (v) then -- look at the value; if there is a URL add an error message
table.insert (error_list, utilities.wrap_style ('parameter', k));
end
end
end
--[[--------------------------< S A F E _ F O R _ U R L >------------------------------------------------------
Escape sequences for content that will be used for URL descriptions
]]
local function safe_for_url( str )
if str:match( "%[%[.-%]%]" ) ~= nil then
utilities.set_message ('err_wikilink_in_url', {});
end
return str:gsub( '[%[%]\n]', {
['['] = '[',
[']'] = ']',
['\n'] = ' ' } );
end
--[[--------------------------< E X T E R N A L _ L I N K >----------------------------------------------------
Format an external link with error checking
]]
local function external_link (URL, label, source, access)
local err_msg = '';
local domain;
local path;
local base_url;
if not utilities.is_set (label) then
label = URL;
if utilities.is_set (source) then
utilities.set_message ('err_bare_url_missing_title', {utilities.wrap_style ('parameter', source)});
else
error (cfg.messages["bare_url_no_origin"]); -- programmer error; valid parameter name does not have matching meta-parameter
end
end
if not check_url (URL) then
utilities.set_message ('err_bad_url', {utilities.wrap_style ('parameter', source)});
end
domain, path = URL:match ('^([/%.%-%+:%a%d]+)([/%?#].*)$'); -- split the URL into scheme plus domain and path
if path then -- if there is a path portion
path = path:gsub ('[%[%]]', {['['] = '%5b', [']'] = '%5d'}); -- replace '[' and ']' with their percent-encoded values
URL = table.concat ({domain, path}); -- and reassemble
end
base_url = table.concat ({ "[", URL, " ", safe_for_url (label), "]" }); -- assemble a wiki-markup URL
if utilities.is_set (access) then -- access level (subscription, registration, limited)
base_url = utilities.substitute (cfg.presentation['ext-link-access-signal'], {cfg.presentation[access].class, cfg.presentation[access].title, base_url}); -- add the appropriate icon
end
return base_url;
end
--[[--------------------------< F O R M A T E _ D A T E >-----------------------------------------------------
Call a calendar module that turns all non-local language dates (including ISO dates) into local language dates.
Used for archiving and review dates.
]]
local function formatDate(txtDateIn, strFormat, params)
local txtDateOut, date, status = boxDate(txtDateIn, strFormat, params)
if status.brk then
return error(status.errorText)
else
return txtDateOut
end
end
--[[--------------------------< D E P R E C A T E D _ P A R A M E T E R >--------------------------------------
Categorize and emit an error message when the citation contains one or more deprecated parameters. The function includes the
offending parameter name to the error message. Only one error message is emitted regardless of the number of deprecated
parameters in the citation.
added_deprecated_cat is a Boolean declared in page scope variables above
]]
local function deprecated_parameter(name)
if not added_deprecated_cat then
added_deprecated_cat = true; -- note that we've added this category
utilities.set_message ('err_deprecated_params', {name}); -- add error message
end
end
--[=[-------------------------< K E R N _ Q U O T E S >--------------------------------------------------------
Apply kerning to open the space between the quote mark provided by the module and a leading or trailing quote
mark contained in a |title= or |chapter= parameter's value.
This function will positive kern either single or double quotes:
"'Unkerned title with leading and trailing single quote marks'"
" 'Kerned title with leading and trailing single quote marks' " (in real life the kerning isn't as wide as this example)
Double single quotes (italic or bold wiki-markup) are not kerned.
Replaces Unicode quote marks in plain text or in the label portion of a [[L|D]] style wikilink with typewriter
quote marks regardless of the need for kerning. Unicode quote marks are not replaced in simple [[D]] wikilinks.
Call this function for chapter titles, for website titles, etc.; not for book titles.
]=]
local function kern_quotes (str)
local cap = '';
local wl_type, label, link;
wl_type, label, link = utilities.is_wikilink (str); -- wl_type is: 0, no wl (text in label variable); 1, [[D]]; 2, [[L|D]]
if 1 == wl_type then -- [[D]] simple wikilink with or without quote marks
if mw.ustring.match (str, '%[%[[\"“”\'‘’].+[\"“”\'‘’]%]%]') then -- leading and trailing quote marks
str = utilities.substitute (cfg.presentation['kern-left'], str);
str = utilities.substitute (cfg.presentation['kern-right'], str);
elseif mw.ustring.match (str, '%[%[[\"“”\'‘’].+%]%]') then -- leading quote marks
str = utilities.substitute (cfg.presentation['kern-left'], str);
elseif mw.ustring.match (str, '%[%[.+[\"“”\'‘’]%]%]') then -- trailing quote marks
str = utilities.substitute (cfg.presentation['kern-right'], str);
end
else -- plain text or [[L|D]]; text in label variable
label = mw.ustring.gsub (label, '[“”]', '\"'); -- replace “” (U+201C & U+201D) with " (typewriter double quote mark)
label = mw.ustring.gsub (label, '[‘’]', '\''); -- replace ‘’ (U+2018 & U+2019) with ' (typewriter single quote mark)
cap = mw.ustring.match (label, "^([\"\'][^\'].+)"); -- match leading double or single quote but not doubled single quotes (italic markup)
if utilities.is_set (cap) then
label = utilities.substitute (cfg.presentation['kern-left'], cap);
end
cap = mw.ustring.match (label, "^(.+[^\'][\"\'])$") -- match trailing double or single quote but not doubled single quotes (italic markup)
if utilities.is_set (cap) then
label = utilities.substitute (cfg.presentation['kern-right'], cap);
end
if 2 == wl_type then
str = utilities.make_wikilink (link, label); -- reassemble the wikilink
else
str = label;
end
end
return str;
end
--[[--------------------------< F O R M A T _ S C R I P T _ V A L U E >----------------------------------------
|script-title= holds title parameters that are not written in Latin-based scripts: Chinese, Japanese, Arabic, Hebrew, etc. These scripts should
not be italicized and may be written right-to-left. The value supplied by |script-title= is concatenated onto Title after Title has been wrapped
in italic markup.
Regardless of language, all values provided by |script-title= are wrapped in <bdi>...</bdi> tags to isolate RTL languages from the English left to right.
|script-title= provides a unique feature. The value in |script-title= may be prefixed with a two-character ISO 639-1 language code and a colon:
|script-title=ja:*** *** (where * represents a Japanese character)
Spaces between the two-character code and the colon and the colon and the first script character are allowed:
|script-title=ja : *** ***
|script-title=ja: *** ***
|script-title=ja :*** ***
Spaces preceding the prefix are allowed: |script-title = ja:*** ***
The prefix is checked for validity. If it is a valid ISO 639-1 language code, the lang attribute (lang="ja") is added to the <bdi> tag so that browsers can
know the language the tag contains. This may help the browser render the script more correctly. If the prefix is invalid, the lang attribute
is not added. At this time there is no error message for this condition.
Supports |script-title=, |script-chapter=, |script-<periodical>=
]]
local function format_script_value (script_value, script_param)
local lang=''; -- initialize to empty string
local name;
if script_value:match('^%l%l%l?%s*:') then -- if first 3 or 4 non-space characters are script language prefix
lang = script_value:match('^(%l%l%l?)%s*:%s*%S.*'); -- get the language prefix or nil if there is no script
if not utilities.is_set (lang) then
utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['missing title part']}); -- prefix without 'title'; add error message
return ''; -- script_value was just the prefix so return empty string
end
-- if we get this far we have prefix and script
name = cfg.lang_tag_remap[lang] or mw.language.fetchLanguageName( lang, cfg.this_wiki_code ); -- get language name so that we can use it to categorize
if utilities.is_set (name) then -- is prefix a proper ISO 639-1 language code?
script_value = script_value:gsub ('^%l+%s*:%s*', ''); -- strip prefix from script
-- is prefix one of these language codes?
if utilities.in_array (lang, cfg.script_lang_codes) then
utilities.add_prop_cat ('script', {name, lang})
else
utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['unknown language code']}); -- unknown script-language; add error message
end
lang = ' lang="' .. lang .. '" '; -- convert prefix into a lang attribute
else
utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['invalid language code']}); -- invalid language code; add error message
lang = ''; -- invalid so set lang to empty string
end
else
utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['missing prefix']}); -- no language code prefix; add error message
end
script_value = utilities.substitute (cfg.presentation['bdi'], {lang, script_value}); -- isolate in case script is RTL
return script_value;
end
--[[--------------------------< S C R I P T _ C O N C A T E N A T E >------------------------------------------
Initially for |title= and |script-title=, this function concatenates those two parameter values after the script
value has been wrapped in <bdi> tags.
]]
local function script_concatenate (title, script, script_param)
if utilities.is_set (script) then
script = format_script_value (script, script_param); -- <bdi> tags, lang attribute, categorization, etc.; returns empty string on error
if utilities.is_set (script) then
title = title .. ' ' .. script; -- concatenate title and script title
end
end
return title;
end
--[[--------------------------< W R A P _ M S G >--------------------------------------------------------------
Applies additional message text to various parameter values. Supplied string is wrapped using a message_list
configuration taking one argument. Supports lower case text for {{citation}} templates. Additional text taken
from citation_config.messages - the reason this function is similar to but separate from wrap_style().
]]
local function wrap_msg (key, str, lower)
if not utilities.is_set ( str ) then
return "";
end
if true == lower then
local msg;
msg = cfg.messages[key]:lower(); -- set the message to lower case before
return utilities.substitute ( msg, str ); -- including template text
else
return utilities.substitute ( cfg.messages[key], str );
end
end
--[[----------------< W I K I S O U R C E _ U R L _ M A K E >-------------------
Makes a Wikisource URL from Wikisource interwiki-link. Returns the URL and appropriate
label; nil else.
str is the value assigned to |chapter= (or aliases) or |title= or |title-link=
]]
local function wikisource_url_make (str)
local wl_type, D, L;
local ws_url, ws_label;
local wikisource_prefix = table.concat ({'https://', cfg.this_wiki_code, '.wikisource.org/wiki/'});
wl_type, D, L = utilities.is_wikilink (str); -- wl_type is 0 (not a wikilink), 1 (simple wikilink), 2 (complex wikilink)
if 0 == wl_type then -- not a wikilink; might be from |title-link=
str = D:match ('^[Ww]ikisource:(.+)') or D:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace
if utilities.is_set (str) then
ws_url = table.concat ({ -- build a Wikisource URL
wikisource_prefix, -- prefix
str, -- article title
});
ws_label = str; -- label for the URL
end
elseif 1 == wl_type then -- simple wikilink: [[Wikisource:ws article]]
str = D:match ('^[Ww]ikisource:(.+)') or D:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace
if utilities.is_set (str) then
ws_url = table.concat ({ -- build a Wikisource URL
wikisource_prefix, -- prefix
str, -- article title
});
ws_label = str; -- label for the URL
end
elseif 2 == wl_type then -- non-so-simple wikilink: [[Wikisource:ws article|displayed text]] ([[L|D]])
str = L:match ('^[Ww]ikisource:(.+)') or L:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace
if utilities.is_set (str) then
ws_label = D; -- get ws article name from display portion of interwiki link
ws_url = table.concat ({ -- build a Wikisource URL
wikisource_prefix, -- prefix
str, -- article title without namespace from link portion of wikilink
});
end
end
if ws_url then
ws_url = mw.uri.encode (ws_url, 'WIKI'); -- make a usable URL
ws_url = ws_url:gsub ('%%23', '#'); -- undo percent-encoding of fragment marker
end
return ws_url, ws_label, L or D; -- return proper URL or nil and a label or nil
end
--[[----------------< F O R M A T _ P E R I O D I C A L >-----------------------
Format the three periodical parameters: |script-<periodical>=, |<periodical>=,
and |trans-<periodical>= into a single Periodical meta-parameter.
]]
local function format_periodical (script_periodical, script_periodical_source, periodical, trans_periodical)
if not utilities.is_set (periodical) then
periodical = ''; -- to be safe for concatenation
else
periodical = utilities.wrap_style ('italic-title', periodical); -- style
end
periodical = script_concatenate (periodical, script_periodical, script_periodical_source); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
if utilities.is_set (trans_periodical) then
trans_periodical = utilities.wrap_style ('trans-italic-title', trans_periodical);
if utilities.is_set (periodical) then
periodical = periodical .. ' ' .. trans_periodical;
else -- here when trans-periodical without periodical or script-periodical
periodical = trans_periodical;
utilities.set_message ('err_trans_missing_title', {'periodical'});
end
end
return periodical;
end
--[[------------------< F O R M A T _ C H A P T E R _ T I T L E >---------------
Format the four chapter parameters: |script-chapter=, |chapter=, |trans-chapter=,
and |chapter-url= into a single chapter meta- parameter (chapter_url_source used
for error messages).
]]
local function format_chapter_title (script_chapter, script_chapter_source, chapter, chapter_source, trans_chapter, trans_chapter_source, chapter_url, chapter_url_source, no_quotes, access)
local ws_url, ws_label, L = wikisource_url_make (chapter); -- make a wikisource URL and label from a wikisource interwiki link
if ws_url then
ws_label = ws_label:gsub ('_', ' '); -- replace underscore separators with space characters
chapter = ws_label;
end
if not utilities.is_set (chapter) then
chapter = ''; -- to be safe for concatenation
else
if false == no_quotes then
chapter = kern_quotes (chapter); -- if necessary, separate chapter title's leading and trailing quote marks from module provided quote marks
chapter = utilities.wrap_style ('quoted-title', chapter);
end
end
chapter = script_concatenate (chapter, script_chapter, script_chapter_source); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
if utilities.is_set (chapter_url) then
chapter = external_link (chapter_url, chapter, chapter_url_source, access); -- adds bare_url_missing_title error if appropriate
elseif ws_url then
chapter = external_link (ws_url, chapter .. ' ', 'ws link in chapter'); -- adds bare_url_missing_title error if appropriate; space char to move icon away from chap text; TODO: better way to do this?
chapter = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, chapter});
end
if utilities.is_set (trans_chapter) then
trans_chapter = utilities.wrap_style ('trans-quoted-title', trans_chapter);
if utilities.is_set (chapter) then
chapter = chapter .. ' ' .. trans_chapter;
else -- here when trans_chapter without chapter or script-chapter
chapter = trans_chapter;
chapter_source = trans_chapter_source:match ('trans%-?(.+)'); -- when no chapter, get matching name from trans-<param>
utilities.set_message ('err_trans_missing_title', {chapter_source});
end
end
return chapter;
end
--[[----------------< H A S _ I N V I S I B L E _ C H A R S >-------------------
This function searches a parameter's value for non-printable or invisible characters.
The search stops at the first match.
This function will detect the visible replacement character when it is part of the Wikisource.
Detects but ignores nowiki and math stripmarkers. Also detects other named stripmarkers
(gallery, math, pre, ref) and identifies them with a slightly different error message.
See also coins_cleanup().
Output of this function is an error message that identifies the character or the
Unicode group, or the stripmarker that was detected along with its position (or,
for multi-byte characters, the position of its first byte) in the parameter value.
]]
local function has_invisible_chars (param, v)
local position = ''; -- position of invisible char or starting position of stripmarker
local capture; -- used by stripmarker detection to hold name of the stripmarker
local stripmarker; -- boolean set true when a stripmarker is found
capture = string.match (v, '[%w%p ]*'); -- test for values that are simple ASCII text and bypass other tests if true
if capture == v then -- if same there are no Unicode characters
return;
end
for _, invisible_char in ipairs (cfg.invisible_chars) do
local char_name = invisible_char[1]; -- the character or group name
local pattern = invisible_char[2]; -- the pattern used to find it
position, _, capture = mw.ustring.find (v, pattern); -- see if the parameter value contains characters that match the pattern
if position and (cfg.invisible_defs.zwj == capture) then -- if we found a zero-width joiner character
if mw.ustring.find (v, cfg.indic_script) then -- it's ok if one of the Indic scripts
position = nil; -- unset position
elseif cfg.emoji_t[mw.ustring.codepoint (v, position+1)] then -- is zwj followed by a character listed in emoji{}?
position = nil; -- unset position
end
end
if position then
if 'nowiki' == capture or 'math' == capture or -- nowiki and math stripmarkers (not an error condition)
('templatestyles' == capture and utilities.in_array (param, {'id', 'quote'})) then -- templatestyles stripmarker allowed in these parameters
stripmarker = true; -- set a flag
elseif true == stripmarker and cfg.invisible_defs.del == capture then -- because stripmakers begin and end with the delete char, assume that we've found one end of a stripmarker
position = nil; -- unset
else
local err_msg;
if capture and not (cfg.invisible_defs.del == capture or cfg.invisible_defs.zwj == capture) then
err_msg = capture .. ' ' .. char_name;
else
err_msg = char_name .. ' ' .. 'character';
end
utilities.set_message ('err_invisible_char', {err_msg, utilities.wrap_style ('parameter', param), position}); -- add error message
return; -- and done with this parameter
end
end
end
end
--[[-------------------< A R G U M E N T _ W R A P P E R >----------------------
Argument wrapper. This function provides support for argument mapping defined
in the configuration file so that multiple names can be transparently aliased to
single internal variable.
]]
local function argument_wrapper ( args )
local origin = {};
return setmetatable({
ORIGIN = function ( self, k )
local dummy = self[k]; -- force the variable to be loaded.
return origin[k];
end
},
{
__index = function ( tbl, k )
if origin[k] ~= nil then
return nil;
end
local args, list, v = args, cfg.aliases[k];
if type( list ) == 'table' then
v, origin[k] = utilities.select_one ( args, list, 'err_redundant_parameters' );
if origin[k] == nil then
origin[k] = ''; -- Empty string, not nil
end
elseif list ~= nil then
v, origin[k] = args[list], list;
else
-- maybe let through instead of raising an error?
-- v, origin[k] = args[k], k;
error( cfg.messages['unknown_argument_map'] .. ': ' .. k);
end
-- Empty strings, not nil;
if v == nil then
v = '';
origin[k] = '';
end
tbl = rawset( tbl, k, v );
return v;
end,
});
end
--[[--------------------------< N O W R A P _ D A T E >-------------------------
When date is YYYY-MM-DD format wrap in nowrap span: <span ...>YYYY-MM-DD</span>.
When date is DD MMMM YYYY or is MMMM DD, YYYY then wrap in nowrap span:
<span ...>DD MMMM</span> YYYY or <span ...>MMMM DD,</span> YYYY
DOES NOT yet support MMMM YYYY or any of the date ranges.
]]
local function nowrap_date (date)
local cap = '';
local cap2 = '';
if date:match("^%d%d%d%d%-%d%d%-%d%d$") then
date = utilities.substitute (cfg.presentation['nowrap1'], date);
elseif date:match("^%a+%s*%d%d?,%s+%d%d%d%d$") or date:match ("^%d%d?%s*%a+%s+%d%d%d%d$") then
cap, cap2 = string.match (date, "^(.*)%s+(%d%d%d%d)$");
date = utilities.substitute (cfg.presentation['nowrap2'], {cap, cap2});
end
return date;
end
--[[--------------------------< S E T _ T I T L E T Y P E >---------------------
This function sets default title types (equivalent to the citation including
|type=<default value>) for those templates that have defaults. Also handles the
special case where it is desirable to omit the title type from the rendered citation
(|type=none).
]]
local function set_titletype (cite_class, title_type)
if utilities.is_set (title_type) then
if 'none' == cfg.keywords_xlate[title_type] then
title_type = ''; -- if |type=none then type parameter not displayed
end
return title_type; -- if |type= has been set to any other value use that value
end
return cfg.title_types [cite_class] or ''; -- set template's default title type; else empty string for concatenation
end
--[[--------------------------< S A F E _ J O I N >-----------------------------
Joins a sequence of strings together while checking for duplicate separation characters.
]]
local function safe_join( tbl, duplicate_char )
local f = {}; -- create a function table appropriate to type of 'duplicate character'
if 1 == #duplicate_char then -- for single byte ASCII characters use the string library functions
f.gsub = string.gsub
f.match = string.match
f.sub = string.sub
else -- for multi-byte characters use the ustring library functions
f.gsub = mw.ustring.gsub
f.match = mw.ustring.match
f.sub = mw.ustring.sub
end
local str = ''; -- the output string
local comp = ''; -- what does 'comp' mean?
local end_chr = '';
local trim;
for _, value in ipairs( tbl ) do
if value == nil then value = ''; end
if str == '' then -- if output string is empty
str = value; -- assign value to it (first time through the loop)
elseif value ~= '' then
if value:sub(1, 1) == '<' then -- special case of values enclosed in spans and other markup.
comp = value:gsub( "%b<>", "" ); -- remove HTML markup (<span>string</span> -> string)
else
comp = value;
end
-- typically duplicate_char is sepc
if f.sub(comp, 1, 1) == duplicate_char then -- is first character same as duplicate_char? why test first character?
-- Because individual string segments often (always?) begin with terminal punct for the
-- preceding segment: 'First element' .. 'sepc next element' .. etc.?
trim = false;
end_chr = f.sub(str, -1, -1); -- get the last character of the output string
-- str = str .. "<HERE(enchr=" .. end_chr .. ")" -- debug stuff?
if end_chr == duplicate_char then -- if same as separator
str = f.sub(str, 1, -2); -- remove it
elseif end_chr == "'" then -- if it might be wiki-markup
if f.sub(str, -3, -1) == duplicate_char .. "''" then -- if last three chars of str are sepc''
str = f.sub(str, 1, -4) .. "''"; -- remove them and add back ''
elseif f.sub(str, -5, -1) == duplicate_char .. "]]''" then -- if last five chars of str are sepc]]''
trim = true; -- why? why do this and next differently from previous?
elseif f.sub(str, -4, -1) == duplicate_char .. "]''" then -- if last four chars of str are sepc]''
trim = true; -- same question
end
elseif end_chr == "]" then -- if it might be wiki-markup
if f.sub(str, -3, -1) == duplicate_char .. "]]" then -- if last three chars of str are sepc]] wikilink
trim = true;
elseif f.sub(str, -3, -1) == duplicate_char .. '"]' then -- if last three chars of str are sepc"] quoted external link
trim = true;
elseif f.sub(str, -2, -1) == duplicate_char .. "]" then -- if last two chars of str are sepc] external link
trim = true;
elseif f.sub(str, -4, -1) == duplicate_char .. "'']" then -- normal case when |url=something & |title=Title.
trim = true;
end
elseif end_chr == " " then -- if last char of output string is a space
if f.sub(str, -2, -1) == duplicate_char .. " " then -- if last two chars of str are <sepc><space>
str = f.sub(str, 1, -3); -- remove them both
end
end
if trim then
if value ~= comp then -- value does not equal comp when value contains HTML markup
local dup2 = duplicate_char;
if f.match(dup2, "%A" ) then dup2 = "%" .. dup2; end -- if duplicate_char not a letter then escape it
value = f.gsub(value, "(%b<>)" .. dup2, "%1", 1 ) -- remove duplicate_char if it follows HTML markup
else
value = f.sub(value, 2, -1 ); -- remove duplicate_char when it is first character
end
end
end
str = str .. value; -- add it to the output string
end
end
return str;
end
--[[--------------------------< I S _ S U F F I X >-----------------------------
returns true if suffix is properly formed Jr, Sr, or ordinal in the range 1–9.
Puncutation not allowed.
]]
local function is_suffix (suffix)
if utilities.in_array (suffix, {'Jr', 'Sr', 'Jnr', 'Snr', '1st', '2nd', '3rd'}) or suffix:match ('^%dth$') then
return true;
end
return false;
end
--[[--------------------< I S _ G O O D _ V A N C _ N A M E >-------------------
For Vancouver style, author/editor names are supposed to be rendered in Latin
(read ASCII) characters. When a name uses characters that contain diacritical
marks, those characters are to be converted to the corresponding Latin
character. When a name is written using a non-Latin alphabet or logogram, that
name is to be transliterated into Latin characters. The module doesn't do this
so editors may/must.
This test allows |first= and |last= names to contain any of the letters defined
in the four Unicode Latin character sets
[http://www.unicode.org/charts/PDF/U0000.pdf C0 Controls and Basic Latin] 0041–005A, 0061–007A
[http://www.unicode.org/charts/PDF/U0080.pdf C1 Controls and Latin-1 Supplement] 00C0–00D6, 00D8–00F6, 00F8–00FF
[http://www.unicode.org/charts/PDF/U0100.pdf Latin Extended-A] 0100–017F
[http://www.unicode.org/charts/PDF/U0180.pdf Latin Extended-B] 0180–01BF, 01C4–024F
|lastn= also allowed to contain hyphens, spaces, and apostrophes.
(http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35029/)
|firstn= also allowed to contain hyphens, spaces, apostrophes, and periods
This original test:
if nil == mw.ustring.find (last, "^[A-Za-zÀ-ÖØ-öø-ƿDŽ-ɏ%-%s%']*$")
or nil == mw.ustring.find (first, "^[A-Za-zÀ-ÖØ-öø-ƿDŽ-ɏ%-%s%'%.]+[2-6%a]*$") then
was written outside of the code editor and pasted here because the code editor
gets confused between character insertion point and cursor position. The test has
been rewritten to use decimal character escape sequence for the individual bytes
of the Unicode characters so that it is not necessary to use an external editor
to maintain this code.
\195\128-\195\150 – À-Ö (U+00C0–U+00D6 – C0 controls)
\195\152-\195\182 – Ø-ö (U+00D8-U+00F6 – C0 controls)
\195\184-\198\191 – ø-ƿ (U+00F8-U+01BF – C0 controls, Latin extended A & B)
\199\132-\201\143 – DŽ-ɏ (U+01C4-U+024F – Latin extended B)
]]
local function is_good_vanc_name (last, first, suffix, position)
if not suffix then
if first:find ('[,%s]') then -- when there is a space or comma, might be first name/initials + generational suffix
first = first:match ('(.-)[,%s]+'); -- get name/initials
suffix = first:match ('[,%s]+(.+)$'); -- get generational suffix
end
end
if utilities.is_set (suffix) then
if not is_suffix (suffix) then
add_vanc_error (cfg.err_msg_supl.suffix, position);
return false; -- not a name with an appropriate suffix
end
end
if nil == mw.ustring.find (last, "^[A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143\225\184\128-\225\187\191%-%s%']*$") or
nil == mw.ustring.find (first, "^[A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143\225\184\128-\225\187\191%-%s%'%.]*$") then
add_vanc_error (cfg.err_msg_supl['non-Latin char'], position);
return false; -- not a string of Latin characters; Vancouver requires Romanization
end;
return true;
end
--[[--------------------------< R E D U C E _ T O _ I N I T I A L S >------------------------------------------
Attempts to convert names to initials in support of |name-list-style=vanc.
Names in |firstn= may be separated by spaces or hyphens, or for initials, a period.
See http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35062/.
Vancouver style requires family rank designations (Jr, II, III, etc.) to be rendered
as Jr, 2nd, 3rd, etc. See http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35085/.
This code only accepts and understands generational suffix in the Vancouver format
because Roman numerals look like, and can be mistaken for, initials.
This function uses ustring functions because firstname initials may be any of the
Unicode Latin characters accepted by is_good_vanc_name ().
]]
local function reduce_to_initials (first, position)
if first:find (',', 1, true) then
return first; -- commas not allowed; abandon
end
local name, suffix = mw.ustring.match (first, "^(%u+) ([%dJS][%drndth]+)$");
if not name then -- if not initials and a suffix
name = mw.ustring.match (first, "^(%u+)$"); -- is it just initials?
end
if name then -- if first is initials with or without suffix
if 3 > mw.ustring.len (name) then -- if one or two initials
if suffix then -- if there is a suffix
if is_suffix (suffix) then -- is it legitimate?
return first; -- one or two initials and a valid suffix so nothing to do
else
add_vanc_error (cfg.err_msg_supl.suffix, position); -- one or two initials with invalid suffix so error message
return first; -- and return first unmolested
end
else
return first; -- one or two initials without suffix; nothing to do
end
end
end -- if here then name has 3 or more uppercase letters so treat them as a word
local initials_t, names_t = {}, {}; -- tables to hold name parts and initials
local i = 1; -- counter for number of initials
names_t = mw.text.split (first, '[%s%-]+'); -- split into a sequence of names and possible suffix
while names_t[i] do -- loop through the sequence
if 1 < i and names_t[i]:match ('[%dJS][%drndth]+%.?$') then -- if not the first name, and looks like a suffix (may have trailing dot)
names_t[i] = names_t[i]:gsub ('%.', ''); -- remove terminal dot if present
if is_suffix (names_t[i]) then -- if a legitimate suffix
table.insert (initials_t, ' ' .. names_t[i]); -- add a separator space, insert at end of initials sequence
break; -- and done because suffix must fall at the end of a name
end -- no error message if not a suffix; possibly because of Romanization
end
if 3 > i then
table.insert (initials_t, mw.ustring.sub (names_t[i], 1, 1)); -- insert the initial at end of initials sequence
end
i = i + 1; -- bump the counter
end
return table.concat (initials_t); -- Vancouver format does not include spaces.
end
--[[--------------------------< I N T E R W I K I _ P R E F I X E N _ G E T >----------------------------------
extract interwiki prefixen from <value>. Returns two one or two values:
false – no prefixen
nil – prefix exists but not recognized
project prefix, language prefix – when value has either of:
:<project>:<language>:<article>
:<language>:<project>:<article>
project prefix, nil – when <value> has only a known single-letter prefix
nil, language prefix – when <value> has only a known language prefix
accepts single-letter project prefixen: 'd' (wikidata), 's' (wikisource), and 'w' (wikipedia) prefixes; at this
writing, the other single-letter prefixen (b (wikibook), c (commons), m (meta), n (wikinews), q (wikiquote), and
v (wikiversity)) are not supported.
]]
local function interwiki_prefixen_get (value, is_link)
if not value:find (':%l+:') then -- if no prefix
return false; -- abandon; boolean here to distinguish from nil fail returns later
end
local prefix_patterns_linked_t = { -- sequence of valid interwiki and inter project prefixen
'^%[%[:([dsw]):(%l%l+):', -- wikilinked; project and language prefixes
'^%[%[:(%l%l+):([dsw]):', -- wikilinked; language and project prefixes
'^%[%[:([dsw]):', -- wikilinked; project prefix
'^%[%[:(%l%l+):', -- wikilinked; language prefix
}
local prefix_patterns_unlinked_t = { -- sequence of valid interwiki and inter project prefixen
'^:([dsw]):(%l%l+):', -- project and language prefixes
'^:(%l%l+):([dsw]):', -- language and project prefixes
'^:([dsw]):', -- project prefix
'^:(%l%l+):', -- language prefix
}
local cap1, cap2;
for _, pattern in ipairs ((is_link and prefix_patterns_linked_t) or prefix_patterns_unlinked_t) do
cap1, cap2 = value:match (pattern);
if cap1 then
break; -- found a match so stop looking
end
end
if cap1 and cap2 then -- when both then :project:language: or :language:project: (both forms allowed)
if 1 == #cap1 then -- length == 1 then :project:language:
if cfg.inter_wiki_map[cap2] then -- is language prefix in the interwiki map?
return cap1, cap2; -- return interwiki project and interwiki language
end
else -- here when :language:project:
if cfg.inter_wiki_map[cap1] then -- is language prefix in the interwiki map?
return cap2, cap1; -- return interwiki project and interwiki language
end
end
return nil; -- unknown interwiki language
elseif not (cap1 or cap2) then -- both are nil?
return nil; -- we got something that looks like a project prefix but isn't; return fail
elseif 1 == #cap1 then -- here when one capture
return cap1, nil; -- length is 1 so return project, nil language
else -- here when one capture and its length it more than 1
if cfg.inter_wiki_map[cap1] then -- is language prefix in the interwiki map?
return nil, cap1; -- return nil project, language
end
end
end
--[[--------------------------< L I S T _ P E O P L E >--------------------------
Formats a list of people (authors, contributors, editors, interviewers, translators)
names in the list will be linked when
|<name>-link= has a value
|<name>-mask- does NOT have a value; masked names are presumed to have been
rendered previously so should have been linked there
when |<name>-mask=0, the associated name is not rendered
]]
local function list_people (control, people, etal)
local sep;
local namesep;
local format = control.format;
local maximum = control.maximum;
local name_list = {};
if 'vanc' == format then -- Vancouver-like name styling?
sep = cfg.presentation['sep_nl_vanc']; -- name-list separator between names is a comma
namesep = cfg.presentation['sep_name_vanc']; -- last/first separator is a space
else
sep = cfg.presentation['sep_nl']; -- name-list separator between names is a semicolon
namesep = cfg.presentation['sep_name']; -- last/first separator is <comma><space>
end
if sep:sub (-1, -1) ~= " " then sep = sep .. " " end
if utilities.is_set (maximum) and maximum < 1 then return "", 0; end -- returned 0 is for EditorCount; not used for other names
for i, person in ipairs (people) do
if utilities.is_set (person.last) then
local mask = person.mask;
local one;
local sep_one = sep;
if utilities.is_set (maximum) and i > maximum then
etal = true;
break;
end
if mask then
local n = tonumber (mask); -- convert to a number if it can be converted; nil else
if n then
one = 0 ~= n and string.rep("—", n) or nil; -- make a string of (n > 0) mdashes, nil else, to replace name
person.link = nil; -- don't create link to name if name is replaces with mdash string or has been set nil
else
one = mask; -- replace name with mask text (must include name-list separator)
sep_one = " "; -- modify name-list separator
end
else
one = person.last; -- get surname
local first = person.first -- get given name
if utilities.is_set (first) then
if ("vanc" == format) then -- if Vancouver format
one = one:gsub ('%.', ''); -- remove periods from surnames (http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35029/)
if not person.corporate and is_good_vanc_name (one, first, nil, i) then -- and name is all Latin characters; corporate authors not tested
first = reduce_to_initials (first, i); -- attempt to convert first name(s) to initials
end
end
one = one .. namesep .. first;
end
end
if utilities.is_set (person.link) then
one = utilities.make_wikilink (person.link, one); -- link author/editor
end
if one then -- if <one> has a value (name, mdash replacement, or mask text replacement)
local proj, tag = interwiki_prefixen_get (one, true); -- get the interwiki prefixen if present
if 'w' == proj and ('Wikipedia' == mw.site.namespaces.Project['name']) then
proj = nil; -- for stuff like :w:de:<article>, :w is unnecessary TODO: maint cat?
end
if proj then
proj = ({['d'] = 'Wikidata', ['s'] = 'Wikisource', ['w'] = 'Wikipedia'})[proj]; -- :w (wikipedia) for linking from a non-wikipedia project
if proj then
one = one .. utilities.wrap_style ('interproj', proj); -- add resized leading space, brackets, static text, language name
tag = nil; -- unset; don't do both project and language
end
end
if tag == cfg.this_wiki_code then
tag = nil; -- stuff like :en:<article> at en.wiki is pointless TODO: maint cat?
end
if tag then
local lang = cfg.lang_tag_remap[tag] or cfg.mw_languages_by_tag_t[tag];
if lang then -- error messaging done in extract_names() where we know parameter names
one = one .. utilities.wrap_style ('interwiki', lang); -- add resized leading space, brackets, static text, language name
end
end
table.insert (name_list, one); -- add it to the list of names
table.insert (name_list, sep_one); -- add the proper name-list separator
end
end
end
local count = #name_list / 2; -- (number of names + number of separators) divided by 2
if 0 < count then
if 1 < count and not etal then
if 'amp' == format then
name_list[#name_list-2] = " & "; -- replace last separator with ampersand text
elseif 'and' == format then
if 2 == count then
name_list[#name_list-2] = cfg.presentation.sep_nl_and; -- replace last separator with 'and' text
else
name_list[#name_list-2] = cfg.presentation.sep_nl_end; -- replace last separator with '(sep) and' text
end
end
end
name_list[#name_list] = nil; -- erase the last separator
end
local result = table.concat (name_list); -- construct list
if etal and utilities.is_set (result) then -- etal may be set by |display-authors=etal but we might not have a last-first list
result = result .. sep .. cfg.messages['et al']; -- we've got a last-first list and etal so add et al.
end
return result, count; -- return name-list string and count of number of names (count used for editor names only)
end
--[[--------------------< M A K E _ C I T E R E F _ I D >-----------------------
Generates a CITEREF anchor ID if we have at least one name or a date. Otherwise
returns an empty string.
namelist is one of the contributor-, author-, or editor-name lists chosen in that
order. year is Year or anchor_year.
]]
local function make_citeref_id (namelist, year)
local names={}; -- a table for the one to four names and year
for i,v in ipairs (namelist) do -- loop through the list and take up to the first four last names
names[i] = v.last
if i == 4 then break end -- if four then done
end
table.insert (names, year); -- add the year at the end
local id = table.concat(names); -- concatenate names and year for CITEREF id
if utilities.is_set (id) then -- if concatenation is not an empty string
return "CITEREF" .. id; -- add the CITEREF portion
else
return ''; -- return an empty string; no reason to include CITEREF id in this citation
end
end
--[[--------------------------< C I T E _ C L A S S _A T T R I B U T E _M A K E >------------------------------
construct <cite> tag class attribute for this citation.
<cite_class> – config.CitationClass from calling template
<mode> – value from |mode= parameter
]]
local function cite_class_attribute_make (cite_class, mode)
local class_t = {};
table.insert (class_t, 'citation'); -- required for blue highlight
if 'citation' ~= cite_class then
table.insert (class_t, cite_class); -- identify this template for user css
table.insert (class_t, utilities.is_set (mode) and mode or 'cs1'); -- identify the citation style for user css or javascript
else
table.insert (class_t, utilities.is_set (mode) and mode or 'cs2'); -- identify the citation style for user css or javascript
end
for _, prop_key in ipairs (z.prop_keys_t) do
table.insert (class_t, prop_key); -- identify various properties for user css or javascript
end
return table.concat (class_t, ' '); -- make a big string and done
end
--[[---------------------< N A M E _ H A S _ E T A L >--------------------------
Evaluates the content of name parameters (author, editor, etc.) for variations on
the theme of et al. If found, the et al. is removed, a flag is set to true and
the function returns the modified name and the flag.
This function never sets the flag to false but returns its previous state because
it may have been set by previous passes through this function or by the associated
|display-<names>=etal parameter
]]
local function name_has_etal (name, etal, nocat, param)
if utilities.is_set (name) then -- name can be nil in which case just return
local patterns = cfg.et_al_patterns; -- get patterns from configuration
for _, pattern in ipairs (patterns) do -- loop through all of the patterns
if name:match (pattern) then -- if this 'et al' pattern is found in name
name = name:gsub (pattern, ''); -- remove the offending text
etal = true; -- set flag (may have been set previously here or by |display-<names>=etal)
if not nocat then -- no categorization for |vauthors=
utilities.set_message ('err_etal', {param}); -- and set an error if not added
end
end
end
end
return name, etal;
end
--[[---------------------< N A M E _ I S _ N U M E R I C >----------------------
Add an error message and category when <name> parameter value does not contain letters.
Add a maintenance category when <name> parameter value has numeric characters mixed with characters that are
not numeric characters; could be letters and/or punctuation characters.
This function will only emit one error and one maint message for the current template. Does not emit both error
and maint messages/categories for the same parameter value.
]]
local function name_is_numeric (name, name_alias, list_name)
local patterns = {
'^%D+%d', -- <name> must have digits preceded by other characters
'^%D*%d+%D+', -- <name> must have digits followed by other characters
}
if not added_numeric_name_errs and mw.ustring.match (name, '^[%A]+$') then -- if we have not already set an error message and <name> does not have any alpha characters
utilities.set_message ('err_numeric_names', name_alias); -- add an error message
added_numeric_name_errs = true; -- set the flag so we emit only one error message
return; -- when here no point in further testing; abandon
end
if not added_numeric_name_maint then -- if we have already set a maint message
for _, pattern in ipairs (patterns) do -- spin through list of patterns
if mw.ustring.match (name, pattern) then -- digits preceded or followed by anything but digits; %D+ includes punctuation
utilities.set_message ('maint_numeric_names', cfg.special_case_translation [list_name]); -- add a maint cat for this template
added_numeric_name_maint = true; -- set the flag so we emit only one maint message
return; -- when here no point in further testing; abandon
end
end
end
end
--[[-----------------< N A M E _ H A S _ M U L T _ N A M E S >------------------
Evaluates the content of last/surname (authors etc.) parameters for multiple names.
Multiple names are indicated if there is more than one comma or any "unescaped"
semicolons. Escaped semicolons are ones used as part of selected HTML entities.
If the condition is met, the function adds the multiple name maintenance category.
Same test for first except that commas should not appear in given names (MOS:JR says
that the generational suffix does not take a separator character). Titles, degrees,
postnominals, affiliations, all normally comma separated don't belong in a citation.
<name> – name parameter value
<list_name> – AuthorList, EditorList, etc
<limit> – number of allowed commas; 1 (default) for surnames; 0 for given names
returns nothing
]]
local function name_has_mult_names (name, list_name, limit)
local _, commas, semicolons, nbsps;
limit = limit and limit or 1;
if utilities.is_set (name) then
_, commas = name:gsub (',', ''); -- count the number of commas
_, semicolons = name:gsub (';', ''); -- count the number of semicolons
-- nbsps probably should be its own separate count rather than merged in
-- some way with semicolons because Lua patterns do not support the
-- grouping operator that regex does, which means there is no way to add
-- more entities to escape except by adding more counts with the new
-- entities
_, nbsps = name:gsub (' ',''); -- count nbsps
-- There is exactly 1 semicolon per entity, so subtract nbsps
-- from semicolons to 'escape' them. If additional entities are added,
-- they also can be subtracted.
if limit < commas or 0 < (semicolons - nbsps) then
utilities.set_message ('maint_mult_names', cfg.special_case_translation [list_name]); -- add a maint message
end
end
end
--[=[-------------------------< I S _ G E N E R I C >----------------------------------------------------------
Compares values assigned to various parameters according to the string provided as <item> in the function call.
<item> can have on of two values:
'generic_names' – for name-holding parameters: |last=, |first=, |editor-last=, etc
'generic_titles' – for |title=
There are two types of generic tests. The 'accept' tests look for a pattern that should not be rejected by the
'reject' test. For example,
|author=[[John Smith (author)|Smith, John]]
would be rejected by the 'author' reject test. But piped wikilinks with 'author' disambiguation should not be
rejected so the 'accept' test prevents that from happening. Accept tests are always performed before reject
tests.
Each of the 'accept' and 'reject' sequence tables hold tables for en.wiki (['en']) and local.wiki (['local'])
that each can hold a test sequence table The sequence table holds, at index [1], a test pattern, and, at index
[2], a boolean control value. The control value tells string.find() or mw.ustring.find() to do plain-text search (true)
or a pattern search (false). The intent of all this complexity is to make these searches as fast as possible so
that we don't run out of processing time on very large articles.
Returns
true when a reject test finds the pattern or string
false when an accept test finds the pattern or string
nil else
]=]
local function is_generic (item, value, wiki)
local test_val;
local str_lower = { -- use string.lower() for en.wiki (['en']) and use mw.ustring.lower() or local.wiki (['local'])
['en'] = string.lower,
['local'] = mw.ustring.lower,
}
local str_find = { -- use string.find() for en.wiki (['en']) and use mw.ustring.find() or local.wiki (['local'])
['en'] = string.find,
['local'] = mw.ustring.find,
}
local function test (val, test_t, wiki) -- local function to do the testing; <wiki> selects lower() and find() functions
val = test_t[2] and str_lower[wiki](value) or val; -- when <test_t[2]> set to 'true', plaintext search using lowercase value
return str_find[wiki] (val, test_t[1], 1, test_t[2]); -- return nil when not found or matched
end
local test_types_t = {'accept', 'reject'}; -- test accept patterns first, then reject patterns
local wikis_t = {'en', 'local'}; -- do tests for each of these keys; en.wiki first, local.wiki second
for _, test_type in ipairs (test_types_t) do -- for each test type
for _, generic_value in pairs (cfg.special_case_translation[item][test_type]) do -- spin through the list of generic value fragments to accept or reject
for _, wiki in ipairs (wikis_t) do
if generic_value[wiki] then
if test (value, generic_value[wiki], wiki) then -- go do the test
return ('reject' == test_type); -- param value rejected, return true; false else
end
end
end
end
end
end
--[[--------------------------< N A M E _ I S _ G E N E R I C >------------------------------------------------
calls is_generic() to determine if <name> is a 'generic name' listed in cfg.generic_names; <name_alias> is the
parameter name used in error messaging
]]
local function name_is_generic (name, name_alias)
if not added_generic_name_errs and is_generic ('generic_names', name) then
utilities.set_message ('err_generic_name', name_alias); -- set an error message
added_generic_name_errs = true;
end
end
--[[--------------------------< N A M E _ C H E C K S >--------------------------------------------------------
This function calls various name checking functions used to validate the content of the various name-holding parameters.
]]
local function name_checks (last, first, list_name, last_alias, first_alias)
local accept_name;
if utilities.is_set (last) then
last, accept_name = utilities.has_accept_as_written (last); -- remove accept-this-as-written markup when it wraps all of <last>
if not accept_name then -- <last> not wrapped in accept-as-written markup
name_has_mult_names (last, list_name); -- check for multiple names in the parameter
name_is_numeric (last, last_alias, list_name); -- check for names that have no letters or are a mix of digits and other characters
name_is_generic (last, last_alias); -- check for names found in the generic names list
end
end
if utilities.is_set (first) then
first, accept_name = utilities.has_accept_as_written (first); -- remove accept-this-as-written markup when it wraps all of <first>
if not accept_name then -- <first> not wrapped in accept-as-written markup
name_has_mult_names (first, list_name, 0); -- check for multiple names in the parameter; 0 is number of allowed commas in a given name
name_is_numeric (first, first_alias, list_name); -- check for names that have no letters or are a mix of digits and other characters
name_is_generic (first, first_alias); -- check for names found in the generic names list
end
local wl_type, D = utilities.is_wikilink (first);
if 0 ~= wl_type then
first = D;
utilities.set_message ('err_bad_paramlink', first_alias);
end
end
return last, first; -- done
end
--[[----------------------< E X T R A C T _ N A M E S >-------------------------
Gets name list from the input arguments
Searches through args in sequential order to find |lastn= and |firstn= parameters
(or their aliases), and their matching link and mask parameters. Stops searching
when both |lastn= and |firstn= are not found in args after two sequential attempts:
found |last1=, |last2=, and |last3= but doesn't find |last4= and |last5= then the
search is done.
This function emits an error message when there is a |firstn= without a matching
|lastn=. When there are 'holes' in the list of last names, |last1= and |last3=
are present but |last2= is missing, an error message is emitted. |lastn= is not
required to have a matching |firstn=.
When an author or editor parameter contains some form of 'et al.', the 'et al.'
is stripped from the parameter and a flag (etal) returned that will cause list_people()
to add the static 'et al.' text from Module:Citation/CS1/Configuration. This keeps
'et al.' out of the template's metadata. When this occurs, an error is emitted.
]]
local function extract_names(args, list_name)
local names = {}; -- table of names
local last; -- individual name components
local first;
local link;
local mask;
local i = 1; -- loop counter/indexer
local n = 1; -- output table indexer
local count = 0; -- used to count the number of times we haven't found a |last= (or alias for authors, |editor-last or alias for editors)
local etal = false; -- return value set to true when we find some form of et al. in an author parameter
local last_alias, first_alias, link_alias; -- selected parameter aliases used in error messaging
while true do
last, last_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'err_redundant_parameters', i ); -- search through args for name components beginning at 1
first, first_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'err_redundant_parameters', i );
link, link_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-Link'], 'err_redundant_parameters', i );
mask = utilities.select_one ( args, cfg.aliases[list_name .. '-Mask'], 'err_redundant_parameters', i );
if last then -- error check |lastn= alias for unknown interwiki link prefix; done here because this is where we have the parameter name
local project, language = interwiki_prefixen_get (last, true); -- true because we expect interwiki links in |lastn= to be wikilinked
if nil == project and nil == language then -- when both are nil
utilities.set_message ('err_bad_paramlink', last_alias); -- not known, emit an error message -- TODO: err_bad_interwiki?
last = utilities.remove_wiki_link (last); -- remove wikilink markup; show display value only
end
end
if link then -- error check |linkn= alias for unknown interwiki link prefix
local project, language = interwiki_prefixen_get (link, false); -- false because wiki links in |author-linkn= is an error
if nil == project and nil == language then -- when both are nil
utilities.set_message ('err_bad_paramlink', link_alias); -- not known, emit an error message -- TODO: err_bad_interwiki?
link = nil; -- unset so we don't link
link_alias = nil;
end
end
last, etal = name_has_etal (last, etal, false, last_alias); -- find and remove variations on et al.
first, etal = name_has_etal (first, etal, false, first_alias); -- find and remove variations on et al.
last, first = name_checks (last, first, list_name, last_alias, first_alias); -- multiple names, extraneous annotation, etc. checks
if first and not last then -- if there is a firstn without a matching lastn
local alias = first_alias:find ('given', 1, true) and 'given' or 'first'; -- get first or given form of the alias
utilities.set_message ('err_first_missing_last', {
first_alias, -- param name of alias missing its mate
first_alias:gsub (alias, {['first'] = 'last', ['given'] = 'surname'}), -- make param name appropriate to the alias form
}); -- add this error message
elseif not first and not last then -- if both firstn and lastn aren't found, are we done?
count = count + 1; -- number of times we haven't found last and first
if 2 <= count then -- two missing names and we give up
break; -- normal exit or there is a two-name hole in the list; can't tell which
end
else -- we have last with or without a first
local result;
link = link_title_ok (link, link_alias, last, last_alias); -- check for improper wiki-markup
if first then
link = link_title_ok (link, link_alias, first, first_alias); -- check for improper wiki-markup
end
names[n] = {last = last, first = first, link = link, mask = mask, corporate = false}; -- add this name to our names list (corporate for |vauthors= only)
n = n + 1; -- point to next location in the names table
if 1 == count then -- if the previous name was missing
utilities.set_message ('err_missing_name', {list_name:match ("(%w+)List"):lower(), i - 1}); -- add this error message
end
count = 0; -- reset the counter, we're looking for two consecutive missing names
end
i = i + 1; -- point to next args location
end
return names, etal; -- all done, return our list of names and the etal flag
end
--[[--------------------------< N A M E _ T A G _ G E T >------------------------------------------------------
attempt to decode |language=<lang_param> and return language name and matching tag; nil else.
This function looks for:
<lang_param> as a tag in cfg.lang_tag_remap{}
<lang_param> as a name in cfg.lang_name_remap{}
<lang_param> as a name in cfg.mw_languages_by_name_t
<lang_param> as a tag in cfg.mw_languages_by_tag_t
when those fail, presume that <lang_param> is an IETF-like tag that MediaWiki does not recognize. Strip all
script, region, variant, whatever subtags from <lang_param> to leave just a two or three character language tag
and look for the new <lang_param> in cfg.mw_languages_by_tag_t{}
on success, returns name (in properly capitalized form) and matching tag (in lowercase); on failure returns nil
]]
local function name_tag_get (lang_param)
local lang_param_lc = mw.ustring.lower (lang_param); -- use lowercase as an index into the various tables
local name;
local tag;
name = cfg.lang_tag_remap[lang_param_lc]; -- assume <lang_param_lc> is a tag; attempt to get remapped language name
if name then -- when <name>, <lang_param> is a tag for a remapped language name
if cfg.lang_name_remap[name:lower()][2] ~= lang_param_lc then
utilities.set_message ('maint_unknown_lang'); -- add maint category if not already added
return name, cfg.lang_name_remap[name:lower()][2]; -- so return name and tag from lang_name_remap[name]; special case to xlate sr-ec and sr-el to sr-cyrl and sr-latn
end
return name, lang_param_lc; -- so return <name> from remap and <lang_param_lc>
end
tag = lang_param_lc:match ('^(%a%a%a?)%-.*'); -- still assuming that <lang_param_lc> is a tag; strip script, region, variant subtags
name = cfg.lang_tag_remap[tag]; -- attempt to get remapped language name with language subtag only
if name then -- when <name>, <tag> is a tag for a remapped language name
return name, tag; -- so return <name> from remap and <tag>
end
if cfg.lang_name_remap[lang_param_lc] then -- not a remapped tag, assume <lang_param_lc> is a name; attempt to get remapped language tag
return cfg.lang_name_remap[lang_param_lc][1], cfg.lang_name_remap[lang_param_lc][2]; -- for this <lang_param_lc>, return a (possibly) new name and appropriate tag
end
name = cfg.mw_languages_by_tag_t[lang_param_lc]; -- assume that <lang_param_lc> is a tag; attempt to get its matching language name
if name then
return name, lang_param_lc; -- <lang_param_lc> is a tag so return it and <name>
end
tag = cfg.mw_languages_by_name_t[lang_param_lc]; -- assume that <lang_param_lc> is a language name; attempt to get its matching tag
if tag then
return cfg.mw_languages_by_tag_t[tag], tag; -- <lang_param_lc> is a name so return the name from the table and <tag>
end
tag = lang_param_lc:match ('^(%a%a%a?)%-.*'); -- is <lang_param_lc> an IETF-like tag that MediaWiki doesn't recognize? <tag> gets the language subtag; nil else
if tag then
name = cfg.mw_languages_by_tag_t[tag]; -- attempt to get a language name using the shortened <tag>
if name then
return name, tag; -- <lang_param_lc> is an unrecognized IETF-like tag so return <name> and language subtag
end
end
end
--[[-------------------< L A N G U A G E _ P A R A M E T E R >------------------
Gets language name from a provided two- or three-character ISO 639 code. If a code
is recognized by MediaWiki, use the returned name; if not, then use the value that
was provided with the language parameter.
When |language= contains a recognized language (either code or name), the page is
assigned to the category for that code: Category:Norwegian-language sources (no).
For valid three-character code languages, the page is assigned to the single category
for '639-2' codes: Category:CS1 ISO 639-2 language sources.
Languages that are the same as the local wiki are not categorized. MediaWiki does
not recognize three-character equivalents of two-character codes: code 'ar' is
recognized but code 'ara' is not.
This function supports multiple languages in the form |language=nb, French, th
where the language names or codes are separated from each other by commas with
optional space characters.
]]
local function language_parameter (lang)
local tag; -- some form of IETF-like language tag; language subtag with optional region, sript, vatiant, etc subtags
local lang_subtag; -- ve populates |language= with mostly unecessary region subtags the MediaWiki does not recognize; this is the base language subtag
local name; -- the language name
local language_list = {}; -- table of language names to be rendered
local names_t = {}; -- table made from the value assigned to |language=
local this_wiki_name = mw.language.fetchLanguageName (cfg.this_wiki_code, cfg.this_wiki_code); -- get this wiki's language name
names_t = mw.text.split (lang, '%s*,%s*'); -- names should be a comma separated list
for _, lang in ipairs (names_t) do -- reuse lang here because we don't yet know if lang is a language name or a language tag
local fromEnglishToCode = { -- костыль для РУВИКИ: замена распространённых англоназваний на коды, в следующей итерации использовать Module:Language.
['Arabic'] = 'ar',
['Azerbaijani'] = 'az',
['Belarusian'] = 'be',
['Bulgarian'] = 'bg',
['Czech'] = 'cs',
['Danish'] = 'da',
['German'] = 'de',
['Greek'] = 'el',
['Spanish'] = 'es',
['English'] = 'en',
['Finnish'] = 'fi',
['French'] = 'fr',
['Hebrew'] = 'he',
['Croatian'] = 'hr',
['Hungarian'] = 'hu',
['Armenian'] = 'hy',
['Indonesian'] = 'id',
['Italian'] = 'it',
['Japanese'] = 'ja',
['Korean'] = 'ko',
['Latin'] = 'la',
['Dutch'] = 'nl',
['Norwegian'] = 'no',
['Polish'] = 'pl',
['Portuguese'] = 'pt',
['Romanian'] = 'ro',
['Russian'] = 'ru',
['Slovenian'] = 'sl',
['Serbian'] = 'sr',
['Swedish'] = 'sv',
['Thai'] = 'th',
['Turkish'] = 'tr',
['Ukrainian'] = 'uk',
['Chinese'] = 'zh',
}
if fromEnglishToCode[lang] then
lang = fromEnglishToCode[lang]
end
name, tag = name_tag_get (lang); -- attempt to get name/tag pair for <lang>; <name> has proper capitalization; <tag> is lowercase
if utilities.is_set (tag) then
lang_subtag = tag:gsub ('^(%a%a%a?)%-.*', '%1'); -- for categorization, strip any IETF-like tags from language tag
if cfg.this_wiki_code ~= lang_subtag then -- when the language is not the same as this wiki's language
if 2 == lang_subtag:len() then -- and is a two-character tag
utilities.add_prop_cat ('foreign-lang-source', {name, tag}, lang_subtag); -- categorize it; tag appended to allow for multiple language categorization
else -- or is a recognized language (but has a three-character tag)
utilities.add_prop_cat ('foreign-lang-source-2', {lang_subtag}, lang_subtag); -- categorize it differently TODO: support multiple three-character tag categories per cs1|2 template?
end
elseif cfg.local_lang_cat_enable then -- when the language and this wiki's language are the same and categorization is enabled
utilities.add_prop_cat ('local-lang-source', {name, lang_subtag}); -- categorize it
end
else
name = lang; -- return whatever <lang> has so that we show something
utilities.set_message ('maint_unknown_lang'); -- add maint category if not already added
end
table.insert (language_list, name);
name = ''; -- so we can reuse it
end
name = utilities.make_sep_list (#language_list, language_list);
if (1 == #language_list) and (lang_subtag == cfg.this_wiki_code) then -- when only one language, find lang name in this wiki lang name; for |language=en-us, 'English' in 'American English'
return ''; -- if one language and that language is this wiki's return an empty string (no annotation)
end
return (mw.getCurrentFrame():expandTemplate{ -- РУВИКИ: используем шаблон для отображения языка
title= utilities.substitute (cfg.messages ['language'], tag)
}); -- otherwise wrap with '(in ...)'
--[[ TODO: should only return blank or name rather than full list
so we can clean up the bunched parenthetical elements Language, Type, Format
]]
end
--[[-----------------------< S E T _ C S _ S T Y L E >--------------------------
Gets the default CS style configuration for the given mode.
Returns default separator and either postscript as passed in or the default.
In CS1, the default postscript and separator are '.'.
In CS2, the default postscript is the empty string and the default separator is ','.
]]
local function set_cs_style (postscript, mode)
if utilities.is_set(postscript) then
-- emit a maintenance message if user postscript is the default cs1 postscript
-- we catch the opposite case for cs2 in set_style
if mode == 'cs1' and postscript == cfg.presentation['ps_' .. mode] then
utilities.set_message ('maint_postscript');
end
else
postscript = cfg.presentation['ps_' .. mode];
end
return cfg.presentation['sep_' .. mode], postscript;
end
--[[--------------------------< S E T _ S T Y L E >-----------------------------
Sets the separator and postscript styles. Checks the |mode= first and the
#invoke CitationClass second. Removes the postscript if postscript == none.
]]
local function set_style (mode, postscript, cite_class)
local sep;
if 'cs2' == mode then
sep, postscript = set_cs_style (postscript, 'cs2');
elseif 'cs1' == mode then
sep, postscript = set_cs_style (postscript, 'cs1');
elseif 'citation' == cite_class then
sep, postscript = set_cs_style (postscript, 'cs2');
else
sep, postscript = set_cs_style (postscript, 'cs1');
end
if cfg.keywords_xlate[postscript:lower()] == 'none' then
-- emit a maintenance message if user postscript is the default cs2 postscript
-- we catch the opposite case for cs1 in set_cs_style
if 'cs2' == mode or ('cs1' ~= mode and 'citation' == cite_class) then -- {{citation |title=Title |mode=cs1 |postscript=none}} should not emit maint message
utilities.set_message ('maint_postscript');
end
postscript = '';
end
return sep, postscript
end
--[=[-------------------------< I S _ P D F >-----------------------------------
Determines if a URL has the file extension that is one of the PDF file extensions
used by [[MediaWiki:Common.css]] when applying the PDF icon to external links.
returns true if file extension is one of the recognized extensions, else false
]=]
local function is_pdf (url)
return url:match ('%.pdf$') or url:match ('%.PDF$') or
url:match ('%.pdf[%?#]') or url:match ('%.PDF[%?#]') or
url:match ('%.PDF#') or url:match ('%.pdf#');
end
--[[--------------------------< S T Y L E _ F O R M A T >-----------------------
Applies CSS style to |format=, |chapter-format=, etc. Also emits an error message
if the format parameter does not have a matching URL parameter. If the format parameter
is not set and the URL contains a file extension that is recognized as a PDF document
by MediaWiki's commons.css, this code will set the format parameter to (PDF) with
the appropriate styling.
]]
local function style_format (format, url, fmt_param, url_param)
if utilities.is_set (format) then
format = utilities.wrap_style ('format', format); -- add leading space, parentheses, resize
if not utilities.is_set (url) then
utilities.set_message ('err_format_missing_url', {fmt_param, url_param}); -- add an error message
end
elseif is_pdf (url) then -- format is not set so if URL is a PDF file then
format = utilities.wrap_style ('format', 'PDF'); -- set format to PDF
else
format = ''; -- empty string for concatenation
end
return format;
end
--[[---------------------< G E T _ D I S P L A Y _ N A M E S >------------------
Returns a number that defines the number of names displayed for author and editor
name lists and a Boolean flag to indicate when et al. should be appended to the name list.
When the value assigned to |display-xxxxors= is a number greater than or equal to zero,
return the number and the previous state of the 'etal' flag (false by default
but may have been set to true if the name list contains some variant of the text 'et al.').
When the value assigned to |display-xxxxors= is the keyword 'etal', return a number
that is one greater than the number of authors in the list and set the 'etal' flag true.
This will cause the list_people() to display all of the names in the name list followed by 'et al.'
In all other cases, returns nil and the previous state of the 'etal' flag.
inputs:
max: A['DisplayAuthors'] or A['DisplayEditors'], etc; a number or some flavor of etal
count: #a or #e
list_name: 'authors' or 'editors'
etal: author_etal or editor_etal
This function sets an error message when |display-xxxxors= value greater than or equal to number of names but
not when <max> comes from {{cs1 config}} global settings. When using global settings, <param> is set to the
keyword 'cs1 config' which is used to supress the normal error. Error is suppressed because it is to be expected
that some citations in an article will have the same or fewer names that the limit specified in {{cs1 config}}.
]]
local function get_display_names (max, count, list_name, etal, param)
if utilities.is_set (max) then
if 'etal' == max:lower():gsub("[ '%.]", '') then -- the :gsub() portion makes 'etal' from a variety of 'et al.' spellings and stylings
max = count + 1; -- number of authors + 1 so display all author name plus et al.
etal = true; -- overrides value set by extract_names()
elseif max:match ('^%d+$') then -- if is a string of numbers
max = tonumber (max); -- make it a number
if (max >= count) and ('cs1 config' ~= param) then -- error when local |display-xxxxors= value greater than or equal to number of names; not an error when using global setting
utilities.set_message ('err_disp_name', {param, max}); -- add error message
max = nil;
end
else -- not a valid keyword or number
utilities.set_message ('err_disp_name', {param, max}); -- add error message
max = nil; -- unset; as if |display-xxxxors= had not been set
end
end
return max, etal;
end
--[[----------< E X T R A _ T E X T _ I N _ P A G E _ C H E C K >---------------
Adds error if |page=, |pages=, |quote-page=, |quote-pages= has what appears to be
some form of p. or pp. abbreviation in the first characters of the parameter content.
check page for extraneous p, p., pp, pp., pg, pg. at start of parameter value:
good pattern: '^P[^%.P%l]' matches when page begins PX or P# but not Px
where x and X are letters and # is a digit
bad pattern: '^[Pp][PpGg]' matches when page begins pp, pP, Pp, PP, pg, pG, Pg, PG
]]
local function extra_text_in_page_check (val, name)
if not val:match (cfg.vol_iss_pg_patterns.good_ppattern) then
for _, pattern in ipairs (cfg.vol_iss_pg_patterns.bad_ppatterns) do -- spin through the selected sequence table of patterns
if val:match (pattern) then -- when a match, error so
utilities.set_message ('err_extra_text_pages', name); -- add error message
return; -- and done
end
end
end
end
--[[--------------------------< E X T R A _ T E X T _ I N _ V O L _ I S S _ C H E C K >------------------------
Adds error if |volume= or |issue= has what appears to be some form of redundant 'type' indicator. Applies to
both; this function looks for issue text in both |issue= and |volume= and looks for volume-like text in |voluem=
and |issue=.
For |volume=:
'V.', or 'Vol.' (with or without the dot) abbreviations or 'Volume' in the first characters of the parameter
content (all case insensitive). 'V' and 'v' (without the dot) are presumed to be roman numerals so
are allowed.
For |issue=:
'No.', 'I.', 'Iss.' (with or without the dot) abbreviations, or 'Issue' in the first characters of the
parameter content (all case insensitive); numero styling: 'n°' with degree sign U+00B0, and № precomposed
numero sign U+2116.
Single character values ('v', 'i', 'n') allowed when not followed by separator character ('.', ':', '=', or
whitespace character) – param values are trimmed of whitespace by MediaWiki before delivered to the module.
<val> is |volume= or |issue= parameter value
<name> is |volume= or |issue= parameter name for error message
<selector> is 'v' for |volume=, 'i' for |issue=
sets error message on failure; returns nothing
]]
local function extra_text_in_vol_iss_check (val, name, selector)
if not utilities.is_set (val) then
return;
end
local handler = 'v' == selector and 'err_extra_text_volume' or 'err_extra_text_issue';
val = val:lower(); -- force parameter value to lower case
for _, pattern in ipairs (cfg.vol_iss_pg_patterns.vi_patterns_t) do -- spin through the sequence table of patterns
if val:match (pattern) then -- when a match, error so
utilities.set_message (handler, name); -- add error message
return; -- and done
end
end
end
--[=[-------------------------< G E T _ V _ N A M E _ T A B L E >----------------------------------------------
split apart a |vauthors= or |veditors= parameter. This function allows for corporate names, wrapped in doubled
parentheses to also have commas; in the old version of the code, the doubled parentheses were included in the
rendered citation and in the metadata. Individual author names may be wikilinked
|vauthors=Jones AB, [[E. B. White|White EB]], ((Black, Brown, and Co.))
]=]
local function get_v_name_table (vparam, output_table, output_link_table)
local name_table = mw.text.split(vparam, "%s*,%s*"); -- names are separated by commas
local wl_type, label, link; -- wl_type not used here; just a placeholder
local i = 1;
while name_table[i] do
if name_table[i]:match ('^%(%(.*[^%)][^%)]$') then -- first segment of corporate with one or more commas; this segment has the opening doubled parentheses
local name = name_table[i];
i = i + 1; -- bump indexer to next segment
while name_table[i] do
name = name .. ', ' .. name_table[i]; -- concatenate with previous segments
if name_table[i]:match ('^.*%)%)$') then -- if this table member has the closing doubled parentheses
break; -- and done reassembling so
end
i = i + 1; -- bump indexer
end
table.insert (output_table, name); -- and add corporate name to the output table
table.insert (output_link_table, ''); -- no wikilink
else
wl_type, label, link = utilities.is_wikilink (name_table[i]); -- wl_type is: 0, no wl (text in label variable); 1, [[D]]; 2, [[L|D]]
table.insert (output_table, label); -- add this name
if 1 == wl_type then
table.insert (output_link_table, label); -- simple wikilink [[D]]
else
table.insert (output_link_table, link); -- no wikilink or [[L|D]]; add this link if there is one, else empty string
end
end
i = i + 1;
end
return output_table;
end
--[[--------------------------< P A R S E _ V A U T H O R S _ V E D I T O R S >--------------------------------
This function extracts author / editor names from |vauthors= or |veditors= and finds matching |xxxxor-maskn= and
|xxxxor-linkn= in args. It then returns a table of assembled names just as extract_names() does.
Author / editor names in |vauthors= or |veditors= must be in Vancouver system style. Corporate or institutional names
may sometimes be required and because such names will often fail the is_good_vanc_name() and other format compliance
tests, are wrapped in doubled parentheses ((corporate name)) to suppress the format tests.
Supports generational suffixes Jr, 2nd, 3rd, 4th–6th.
This function sets the Vancouver error when a required comma is missing and when there is a space between an author's initials.
]]
local function parse_vauthors_veditors (args, vparam, list_name)
local names = {}; -- table of names assembled from |vauthors=, |author-maskn=, |author-linkn=
local v_name_table = {};
local v_link_table = {}; -- when name is wikilinked, targets go in this table
local etal = false; -- return value set to true when we find some form of et al. vauthors parameter
local last, first, link, mask, suffix;
local corporate = false;
vparam, etal = name_has_etal (vparam, etal, true); -- find and remove variations on et al. do not categorize (do it here because et al. might have a period)
v_name_table = get_v_name_table (vparam, v_name_table, v_link_table); -- names are separated by commas
for i, v_name in ipairs(v_name_table) do
first = ''; -- set to empty string for concatenation and because it may have been set for previous author/editor
local accept_name;
v_name, accept_name = utilities.has_accept_as_written (v_name); -- remove accept-this-as-written markup when it wraps all of <v_name>
if accept_name then
last = v_name;
corporate = true; -- flag used in list_people()
elseif string.find(v_name, "%s") then
if v_name:find('[;%.]') then -- look for commonly occurring punctuation characters;
add_vanc_error (cfg.err_msg_supl.punctuation, i);
end
local lastfirstTable = {}
lastfirstTable = mw.text.split(v_name, "%s+")
first = table.remove(lastfirstTable); -- removes and returns value of last element in table which should be initials or generational suffix
if not mw.ustring.match (first, '^%u+$') then -- mw.ustring here so that later we will catch non-Latin characters
suffix = first; -- not initials so assume that whatever we got is a generational suffix
first = table.remove(lastfirstTable); -- get what should be the initials from the table
end
last = table.concat(lastfirstTable, ' ') -- returns a string that is the concatenation of all other names that are not initials and generational suffix
if not utilities.is_set (last) then
first = ''; -- unset
last = v_name; -- last empty because something wrong with first
add_vanc_error (cfg.err_msg_supl.name, i);
end
if mw.ustring.match (last, '%a+%s+%u+%s+%a+') then
add_vanc_error (cfg.err_msg_supl['missing comma'], i); -- matches last II last; the case when a comma is missing
end
if mw.ustring.match (v_name, ' %u %u$') then -- this test is in the wrong place TODO: move or replace with a more appropriate test
add_vanc_error (cfg.err_msg_supl.initials, i); -- matches a space between two initials
end
else
last = v_name; -- last name or single corporate name? Doesn't support multiword corporate names? do we need this?
end
if utilities.is_set (first) then
if not mw.ustring.match (first, "^%u?%u$") then -- first shall contain one or two upper-case letters, nothing else
add_vanc_error (cfg.err_msg_supl.initials, i); -- too many initials; mixed case initials (which may be ok Romanization); hyphenated initials
end
is_good_vanc_name (last, first, suffix, i); -- check first and last before restoring the suffix which may have a non-Latin digit
if utilities.is_set (suffix) then
first = first .. ' ' .. suffix; -- if there was a suffix concatenate with the initials
suffix = ''; -- unset so we don't add this suffix to all subsequent names
end
else
if not corporate then
is_good_vanc_name (last, '', nil, i);
end
end
link = utilities.select_one ( args, cfg.aliases[list_name .. '-Link'], 'err_redundant_parameters', i ) or v_link_table[i];
mask = utilities.select_one ( args, cfg.aliases[list_name .. '-Mask'], 'err_redundant_parameters', i );
names[i] = {last = last, first = first, link = link, mask = mask, corporate = corporate}; -- add this assembled name to our names list
end
return names, etal; -- all done, return our list of names
end
--[[--------------------------< S E L E C T _ A U T H O R _ E D I T O R _ S O U R C E >------------------------
Select one of |authors=, |authorn= / |lastn / firstn=, or |vauthors= as the source of the author name list or
select one of |editorn= / editor-lastn= / |editor-firstn= or |veditors= as the source of the editor name list.
Only one of these appropriate three will be used. The hierarchy is: |authorn= (and aliases) highest and |authors= lowest;
|editorn= (and aliases) highest and |veditors= lowest (support for |editors= withdrawn)
When looking for |authorn= / |editorn= parameters, test |xxxxor1= and |xxxxor2= (and all of their aliases); stops after the second
test which mimicks the test used in extract_names() when looking for a hole in the author name list. There may be a better
way to do this, I just haven't discovered what that way is.
Emits an error message when more than one xxxxor name source is provided.
In this function, vxxxxors = vauthors or veditors; xxxxors = authors as appropriate.
]]
local function select_author_editor_source (vxxxxors, xxxxors, args, list_name)
local lastfirst = false;
if utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'none', 1 ) or -- do this twice in case we have a |first1= without a |last1=; this ...
utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'none', 1 ) or -- ... also catches the case where |first= is used with |vauthors=
utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'none', 2 ) or
utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'none', 2 ) then
lastfirst = true;
end
if (utilities.is_set (vxxxxors) and true == lastfirst) or -- these are the three error conditions
(utilities.is_set (vxxxxors) and utilities.is_set (xxxxors)) or
(true == lastfirst and utilities.is_set (xxxxors)) then
local err_name;
if 'AuthorList' == list_name then -- figure out which name should be used in error message
err_name = 'author';
else
err_name = 'editor';
end
utilities.set_message ('err_redundant_parameters', err_name .. '-name-list parameters'); -- add error message
end
if true == lastfirst then return 1 end; -- return a number indicating which author name source to use
if utilities.is_set (vxxxxors) then return 2 end;
if utilities.is_set (xxxxors) then return 3 end;
return 1; -- no authors so return 1; this allows missing author name test to run in case there is a first without last
end
--[[--------------------------< I S _ V A L I D _ P A R A M E T E R _ V A L U E >------------------------------
This function is used to validate a parameter's assigned value for those parameters that have only a limited number
of allowable values (yes, y, true, live, dead, etc.). When the parameter value has not been assigned a value (missing
or empty in the source template) the function returns the value specified by ret_val. If the parameter value is one
of the list of allowed values returns the translated value; else, emits an error message and returns the value
specified by ret_val.
TODO: explain <invert>
]]
local function is_valid_parameter_value (value, name, possible, ret_val, invert)
if not utilities.is_set (value) then
return ret_val; -- an empty parameter is ok
end
if (not invert and utilities.in_array (value, possible)) then -- normal; <value> is in <possible> table
return cfg.keywords_xlate[value]; -- return translation of parameter keyword
elseif invert and not utilities.in_array (value, possible) then -- invert; <value> is not in <possible> table
return value; -- return <value> as it is
else
utilities.set_message ('err_invalid_param_val', {name, value}); -- not an allowed value so add error message
return ret_val;
end
end
--[[--------------------------< T E R M I N A T E _ N A M E _ L I S T >----------------------------------------
This function terminates a name list (author, contributor, editor) with a separator character (sepc) and a space
when the last character is not a sepc character or when the last three characters are not sepc followed by two
closing square brackets (close of a wikilink). When either of these is true, the name_list is terminated with a
single space character.
]]
local function terminate_name_list (name_list, sepc)
if (string.sub (name_list, -3, -1) == sepc .. '. ') then -- if already properly terminated
return name_list; -- just return the name list
elseif (string.sub (name_list, -1, -1) == sepc) or (string.sub (name_list, -3, -1) == sepc .. ']]') then -- if last name in list ends with sepc char
return name_list .. " "; -- don't add another
else
return name_list .. sepc .. ' '; -- otherwise terminate the name list
end
end
--[[-------------------------< F O R M A T _ V O L U M E _ I S S U E >-----------------------------------------
returns the concatenation of the formatted volume and issue (or journal article number) parameters as a single
string; or formatted volume or formatted issue, or an empty string if neither are set.
]]
local function format_volume_issue (volume, issue, article, cite_class, origin, sepc, lower)
if not utilities.is_set (volume) and not utilities.is_set (issue) and not utilities.is_set (article) then
return '';
end
-- same condition as in format_pages_sheets()
local is_journal = 'journal' == cite_class or (utilities.in_array (cite_class, {'citation', 'map', 'interview'}) and 'journal' == origin);
local is_numeric_vol = volume and (volume:match ('^[MDCLXVI]+$') or volume:match ('^%d+$')); -- is only uppercase roman numerals or only digits?
local is_long_vol = volume and (4 < mw.ustring.len(volume)); -- is |volume= value longer than 4 characters?
if volume and (not is_numeric_vol and is_long_vol) then -- when not all digits or Roman numerals, is |volume= longer than 4 characters?
utilities.add_prop_cat ('long-vol'); -- yes, add properties cat
end
if is_journal then -- journal-style formatting
local vol = '';
if utilities.is_set (volume) then
if is_numeric_vol then -- |volume= value all digits or all uppercase Roman numerals?
vol = utilities.substitute (cfg.presentation['vol-bold'], {sepc, volume}); -- render in bold face
elseif is_long_vol then -- not all digits or Roman numerals; longer than 4 characters?
vol = utilities.substitute (cfg.messages['j-vol'], {sepc, utilities.hyphen_to_dash (volume)}); -- not bold
else -- four or fewer characters
vol = utilities.substitute (cfg.presentation['vol-bold'], {sepc, utilities.hyphen_to_dash (volume)}); -- bold
end
end
vol = vol .. (utilities.is_set (issue) and utilities.substitute (cfg.messages['j-issue'], issue) or '')
vol = vol .. (utilities.is_set (article) and utilities.substitute (cfg.messages['j-article-num'], article) or '')
return vol;
end
if 'podcast' == cite_class and utilities.is_set (issue) then
return wrap_msg ('issue', {sepc, issue}, lower);
end
if 'conference' == cite_class and utilities.is_set (article) then -- |article-number= supported only in journal and conference cites
if utilities.is_set (volume) and utilities.is_set (article) then -- both volume and article number
return wrap_msg ('vol-art', {sepc, utilities.hyphen_to_dash (volume), article}, lower);
elseif utilities.is_set (article) then -- article number alone; when volume alone, handled below
return wrap_msg ('art', {sepc, article}, lower);
end
end
-- all other types of citation
if utilities.is_set (volume) and utilities.is_set (issue) then
return wrap_msg ('vol-no', {sepc, utilities.hyphen_to_dash (volume), issue}, lower);
elseif utilities.is_set (volume) then
return wrap_msg ('vol', {sepc, utilities.hyphen_to_dash (volume)}, lower);
else
return wrap_msg ('issue', {sepc, issue}, lower);
end
end
--[[-------------------------< F O R M A T _ P A G E S _ S H E E T S >-----------------------------------------
adds static text to one of |page(s)= or |sheet(s)= values and returns it with all of the others set to empty strings.
The return order is:
page, pages, sheet, sheets
Singular has priority over plural when both are provided.
]]
local function format_pages_sheets (page, pages, sheet, sheets, cite_class, origin, sepc, nopp, lower)
if 'map' == cite_class then -- only cite map supports sheet(s) as in-source locators
if utilities.is_set (sheet) then
if 'journal' == origin then
return '', '', wrap_msg ('j-sheet', sheet, lower), '';
else
return '', '', wrap_msg ('sheet', {sepc, sheet}, lower), '';
end
elseif utilities.is_set (sheets) then
if 'journal' == origin then
return '', '', '', wrap_msg ('j-sheets', sheets, lower);
else
return '', '', '', wrap_msg ('sheets', {sepc, sheets}, lower);
end
end
end
local is_journal = 'journal' == cite_class or (utilities.in_array (cite_class, {'citation', 'map', 'interview'}) and 'journal' == origin);
if utilities.is_set (page) then
if is_journal then
return utilities.substitute (cfg.messages['j-page(s)'], page), '', '', '';
elseif not nopp then
return utilities.substitute (cfg.messages['p-prefix'], {sepc, page}), '', '', '';
else
return utilities.substitute (cfg.messages['nopp'], {sepc, page}), '', '', '';
end
elseif utilities.is_set (pages) then
if is_journal then
return utilities.substitute (cfg.messages['j-page(s)'], pages), '', '', '';
elseif tonumber(pages) ~= nil and not nopp then -- if pages is only digits, assume a single page number
return '', utilities.substitute (cfg.messages['p-prefix'], {sepc, pages}), '', '';
elseif not nopp then
return '', utilities.substitute (cfg.messages['pp-prefix'], {sepc, pages}), '', '';
else
return '', utilities.substitute (cfg.messages['nopp'], {sepc, pages}), '', '';
end
end
return '', '', '', ''; -- return empty strings
end
--[[--------------------------< I N S O U R C E _ L O C _ G E T >----------------------------------------------
returns one of the in-source locators: page, pages, or at.
If any of these are interwiki links to Wikisource, returns the label portion of the interwiki-link as plain text
for use in COinS. This COinS thing is done because here we convert an interwiki-link to an external link and
add an icon span around that; get_coins_pages() doesn't know about the span. TODO: should it?
TODO: add support for sheet and sheets?; streamline;
TODO: make it so that this function returns only one of the three as the single in-source (the return value assigned
to a new name)?
]]
local function insource_loc_get (page, page_orig, pages, pages_orig, at)
local ws_url, ws_label, coins_pages, L; -- for Wikisource interwiki-links; TODO: this corrupts page metadata (span remains in place after cleanup; fix there?)
if utilities.is_set (page) then
if utilities.is_set (pages) or utilities.is_set (at) then
pages = ''; -- unset the others
at = '';
end
extra_text_in_page_check (page, page_orig); -- emit error message when |page= value begins with what looks like p., pp., etc.
ws_url, ws_label, L = wikisource_url_make (page); -- make ws URL from |page= interwiki link; link portion L becomes tooltip label
if ws_url then
page = external_link (ws_url, ws_label .. ' ', 'ws link in page'); -- space char after label to move icon away from in-source text; TODO: a better way to do this?
page = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, page});
coins_pages = ws_label;
end
elseif utilities.is_set (pages) then
if utilities.is_set (at) then
at = ''; -- unset
end
extra_text_in_page_check (pages, pages_orig); -- emit error message when |page= value begins with what looks like p., pp., etc.
ws_url, ws_label, L = wikisource_url_make (pages); -- make ws URL from |pages= interwiki link; link portion L becomes tooltip label
if ws_url then
pages = external_link (ws_url, ws_label .. ' ', 'ws link in pages'); -- space char after label to move icon away from in-source text; TODO: a better way to do this?
pages = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, pages});
coins_pages = ws_label;
end
elseif utilities.is_set (at) then
ws_url, ws_label, L = wikisource_url_make (at); -- make ws URL from |at= interwiki link; link portion L becomes tooltip label
if ws_url then
at = external_link (ws_url, ws_label .. ' ', 'ws link in at'); -- space char after label to move icon away from in-source text; TODO: a better way to do this?
at = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, at});
coins_pages = ws_label;
end
end
return page, pages, at, coins_pages;
end
--[[--------------------------< I S _ U N I Q U E _ A R C H I V E _ U R L >------------------------------------
add error message when |archive-url= value is same as |url= or chapter-url= (or alias...) value
]]
local function is_unique_archive_url (archive, url, c_url, source, date)
if utilities.is_set (archive) then
if archive == url or archive == c_url then
utilities.set_message ('err_bad_url', {utilities.wrap_style ('parameter', source)}); -- add error message
return '', ''; -- unset |archive-url= and |archive-date= because same as |url= or |chapter-url=
end
end
return archive, date;
end
--[=[-------------------------< A R C H I V E _ U R L _ C H E C K >--------------------------------------------
Check archive.org URLs to make sure they at least look like they are pointing at valid archives and not to the
save snapshot URL or to calendar pages. When the archive URL is 'https://web.archive.org/save/' (or http://...)
archive.org saves a snapshot of the target page in the URL. That is something that Wikipedia should not allow
unwitting readers to do.
When the archive.org URL does not have a complete timestamp, archive.org chooses a snapshot according to its own
algorithm or provides a calendar 'search' result. [[WP:ELNO]] discourages links to search results.
This function looks at the value assigned to |archive-url= and returns empty strings for |archive-url= and
|archive-date= and an error message when:
|archive-url= holds an archive.org save command URL
|archive-url= is an archive.org URL that does not have a complete timestamp (YYYYMMDDhhmmss 14 digits) in the
correct place
otherwise returns |archive-url= and |archive-date=
There are two mostly compatible archive.org URLs:
//web.archive.org/<timestamp>... -- the old form
//web.archive.org/web/<timestamp>... -- the new form
The old form does not support or map to the new form when it contains a display flag. There are four identified flags
('id_', 'js_', 'cs_', 'im_') but since archive.org ignores others following the same form (two letters and an underscore)
we don't check for these specific flags but we do check the form.
This function supports a preview mode. When the article is rendered in preview mode, this function may return a modified
archive URL:
for save command errors, return undated wildcard (/*/)
for timestamp errors when the timestamp has a wildcard, return the URL unmodified
for timestamp errors when the timestamp does not have a wildcard, return with timestamp limited to six digits plus wildcard (/yyyymm*/)
A secondary function is to return an archive-url timestamp from those urls that have them (archive.org and
archive.today). The timestamp is used by validation.archive_date_check() to see if the value in |archive-date=
matches the timestamp in the archive url.
]=]
local function archive_url_check (url, date)
local err_msg = ''; -- start with the error message empty
local path, timestamp, flag; -- portions of the archive.org URL
timestamp = url:match ('//archive.today/(%d%d%d%d%d%d%d%d%d%d%d%d%d%d)/') or -- get timestamp from archive.today urls
url:match ('//archive.today/(%d%d%d%d%.%d%d%.%d%d%-%d%d%d%d%d%d)/'); -- this timestamp needs cleanup
if timestamp then -- if this was an archive.today url ...
return url, date, timestamp:gsub ('[%.%-]', ''); -- return ArchiveURL, ArchiveDate, and timestamp (dots and dashes removed) from |archive-url=, and done -- return ArchiveURL, ArchiveDate, and timestamp from |archive-url=, and done
end
-- here for archive.org urls
if (not url:match('//web%.archive%.org/')) and (not url:match('//liveweb%.archive%.org/')) then -- also deprecated liveweb Wayback machine URL
return url, date; -- not an archive.org archive, return ArchiveURL and ArchiveDate
end
if url:match('//web%.archive%.org/save/') then -- if a save command URL, we don't want to allow saving of the target page
err_msg = cfg.err_msg_supl.save;
url = url:gsub ('(//web%.archive%.org)/save/', '%1/*/', 1); -- for preview mode: modify ArchiveURL
elseif url:match('//liveweb%.archive%.org/') then
err_msg = cfg.err_msg_supl.liveweb;
else
path, timestamp, flag = url:match('//web%.archive%.org/([^%d]*)(%d+)([^/]*)/'); -- split out some of the URL parts for evaluation
if not path then -- malformed in some way; pattern did not match
err_msg = cfg.err_msg_supl.timestamp;
elseif 14 ~= timestamp:len() then -- path and flag optional, must have 14-digit timestamp here
err_msg = cfg.err_msg_supl.timestamp;
if '*' ~= flag then
local replacement = timestamp:match ('^%d%d%d%d%d%d') or timestamp:match ('^%d%d%d%d'); -- get the first 6 (YYYYMM) or first 4 digits (YYYY)
if replacement then -- nil if there aren't at least 4 digits (year)
replacement = replacement .. string.rep ('0', 14 - replacement:len()); -- year or yearmo (4 or 6 digits) zero-fill to make 14-digit timestamp
url=url:gsub ('(//web%.archive%.org/[^%d]*)%d[^/]*', '%1' .. replacement .. '*', 1) -- for preview, modify ts to 14 digits plus splat for calendar display
end
end
elseif utilities.is_set (path) and 'web/' ~= path then -- older archive URLs do not have the extra 'web/' path element
err_msg = cfg.err_msg_supl.path;
elseif utilities.is_set (flag) and not utilities.is_set (path) then -- flag not allowed with the old form URL (without the 'web/' path element)
err_msg = cfg.err_msg_supl.flag;
elseif utilities.is_set (flag) and not flag:match ('%a%a_') then -- flag if present must be two alpha characters and underscore (requires 'web/' path element)
err_msg = cfg.err_msg_supl.flag;
else
return url, date, timestamp; -- return ArchiveURL, ArchiveDate, and timestamp from |archive-url=
end
end
-- if here, something not right so
utilities.set_message ('err_archive_url', {err_msg}); -- add error message and
if is_preview_mode then
return url, date, timestamp; -- preview mode so return ArchiveURL, ArchiveDate, and timestamp from |archive-url=
else
return '', ''; -- return empty strings for ArchiveURL and ArchiveDate
end
end
--[[--------------------------< P L A C E _ C H E C K >--------------------------------------------------------
check |place=, |publication-place=, |location= to see if these params include digits. This function added because
many editors misuse location to specify the in-source location (|page(s)= and |at= are supposed to do that)
returns the original parameter value without modification; added maint cat when parameter value contains digits
]]
local function place_check (param_val)
if not utilities.is_set (param_val) then -- parameter empty or omitted
return param_val; -- return that empty state
end
if mw.ustring.find (param_val, '%d') then -- not empty, are there digits in the parameter value
utilities.set_message ('maint_location'); -- yep, add maint cat
end
return param_val; -- and done
end
--[[--------------------------< I S _ A R C H I V E D _ C O P Y >----------------------------------------------
compares |title= to 'Archived copy' (placeholder added by bots that can't find proper title); if matches, return true; nil else
]]
local function is_archived_copy (title)
title = mw.ustring.lower(title); -- switch title to lower case
if title:find (cfg.special_case_translation.archived_copy.en) then -- if title is 'Archived copy'
return true;
elseif cfg.special_case_translation.archived_copy['local'] then
if mw.ustring.find (title, cfg.special_case_translation.archived_copy['local']) then -- mw.ustring() because might not be Latin script
return true;
end
end
end
--[[--------------------------< D I S P L A Y _ N A M E S _ S E L E C T >--------------------------------------
for any of the |display-authors=, |display-editors=, etc parameters, select either the local or global setting.
When both are present, look at <local_display_names> value. When the value is some sort of 'et al.'string,
special handling is required.
When {{cs1 config}} has |display-<namelist>= AND this template has |display-<namelist>=etal AND:
the number of names specified by <number_of_names> is:
greater than the number specified in the global |display-<namelist>= parameter (<global_display_names>)
use global |display-<namelist>= parameter value
set overridden maint category
less than or equal to the number specified in the global |display-<namelist>= parameter
use local |display-<namelist>= parameter value
The purpose of this function is to prevent categorizing a template that has fewer names than the global setting
to keep the etal annotation specified by <local_display_names>.
]]
local function display_names_select (global_display_names, local_display_names, param_name, number_of_names, test)
if global_display_names and utilities.is_set (local_display_names) then -- when both
if 'etal' == local_display_names:lower():gsub("[ '%.]", '') then -- the :gsub() portion makes 'etal' from a variety of 'et al.' spellings and stylings
number_of_names = tonumber (number_of_names); -- convert these to numbers for comparison
local global_display_names_num = tonumber (global_display_names); -- <global_display_names> not set when parameter value is not digits
if number_of_names > global_display_names_num then -- template has more names than global config allows to be displayed?
utilities.set_message ('maint_overridden_setting'); -- set a maint message because global is overriding local |display-<namelist>=etal
return global_display_names, 'cs1 config'; -- return global with spoof parameter name (for get_display_names())
else
return local_display_names, param_name; -- return local because fewer names so let <local_display_names> control
end
end
-- here when <global_display_names> and <local_display_names> both numbers; <global_display_names> controls
utilities.set_message ('maint_overridden_setting'); -- set a maint message
return global_display_names, 'cs1 config'; -- return global with spoof parameter name (for get_display_names())
end
-- here when only one of <global_display_names> or <local_display_names> set
if global_display_names then
return global_display_names, 'cs1 config'; -- return global with spoof parameter name (for get_display_names())
else
return local_display_names, param_name; -- return local
end
end
--[[--------------------------< C I T A T I O N 0 >------------------------------------------------------------
This is the main function doing the majority of the citation formatting.
]]
local function citation0( config, args )
--[[
Load Input Parameters
The argument_wrapper facilitates the mapping of multiple aliases to single internal variable.
]]
local A = argument_wrapper ( args );
local i
-- Pick out the relevant fields from the arguments. Different citation templates
-- define different field names for the same underlying things.
local author_etal;
local a = {}; -- authors list from |lastn= / |firstn= pairs or |vauthors=
local Authors;
local NameListStyle;
if cfg.global_cs1_config_t['NameListStyle'] then -- global setting in {{cs1 config}} overrides local |name-list-style= parameter value; nil when empty or assigned value invalid
NameListStyle = is_valid_parameter_value (cfg.global_cs1_config_t['NameListStyle'], 'cs1 config: name-list-style', cfg.keywords_lists['name-list-style'], ''); -- error messaging 'param' here is a hoax
else
NameListStyle = is_valid_parameter_value (A['NameListStyle'], A:ORIGIN('NameListStyle'), cfg.keywords_lists['name-list-style'], '');
end
if cfg.global_cs1_config_t['NameListStyle'] and utilities.is_set (A['NameListStyle']) then -- when template has |name-list-style=<something> which global setting has overridden
utilities.set_message ('maint_overridden_setting'); -- set a maint message
end
local Collaboration = A['Collaboration'];
do -- to limit scope of selected
local selected = select_author_editor_source (A['Vauthors'], A['Authors'], args, 'AuthorList');
if 1 == selected then
a, author_etal = extract_names (args, 'AuthorList'); -- fetch author list from |authorn= / |lastn= / |firstn=, |author-linkn=, and |author-maskn=
elseif 2 == selected then
NameListStyle = 'vanc'; -- override whatever |name-list-style= might be
a, author_etal = parse_vauthors_veditors (args, A['Vauthors'], 'AuthorList'); -- fetch author list from |vauthors=, |author-linkn=, and |author-maskn=
elseif 3 == selected then
Authors = A['Authors']; -- use content of |authors=
end
if utilities.is_set (Collaboration) then
author_etal = true; -- so that |display-authors=etal not required
end
end
local editor_etal;
local e = {}; -- editors list from |editor-lastn= / |editor-firstn= pairs or |veditors=
do -- to limit scope of selected
local selected = select_author_editor_source (A['Veditors'], nil, args, 'EditorList'); -- support for |editors= withdrawn
if 1 == selected then
e, editor_etal = extract_names (args, 'EditorList'); -- fetch editor list from |editorn= / |editor-lastn= / |editor-firstn=, |editor-linkn=, and |editor-maskn=
elseif 2 == selected then
NameListStyle = 'vanc'; -- override whatever |name-list-style= might be
e, editor_etal = parse_vauthors_veditors (args, args.veditors, 'EditorList'); -- fetch editor list from |veditors=, |editor-linkn=, and |editor-maskn=
end
end
local Chapter = A['Chapter']; -- done here so that we have access to |contribution= from |chapter= aliases
local Chapter_origin = A:ORIGIN ('Chapter');
local Contribution; -- because contribution is required for contributor(s)
if 'contribution' == Chapter_origin then
Contribution = Chapter; -- get the name of the contribution
end
local c = {}; -- contributors list from |contributor-lastn= / contributor-firstn= pairs
if utilities.in_array (config.CitationClass, {"book", "citation"}) and not utilities.is_set (A['Periodical']) then -- |contributor= and |contribution= only supported in book cites
c = extract_names (args, 'ContributorList'); -- fetch contributor list from |contributorn= / |contributor-lastn=, -firstn=, -linkn=, -maskn=
if 0 < #c then
if not utilities.is_set (Contribution) then -- |contributor= requires |contribution=
utilities.set_message ('err_contributor_missing_required_param', 'contribution'); -- add missing contribution error message
c = {}; -- blank the contributors' table; it is used as a flag later
end
if 0 == #a then -- |contributor= requires |author=
utilities.set_message ('err_contributor_missing_required_param', 'author'); -- add missing author error message
c = {}; -- blank the contributors' table; it is used as a flag later
end
end
else -- if not a book cite
if utilities.select_one (args, cfg.aliases['ContributorList-Last'], 'err_redundant_parameters', 1 ) then -- are there contributor name list parameters?
utilities.set_message ('err_contributor_ignored'); -- add contributor ignored error message
end
Contribution = nil; -- unset
end
local Title = A['Title'];
local TitleLink = A['TitleLink'];
local auto_select = ''; -- default is auto
local accept_link;
TitleLink, accept_link = utilities.has_accept_as_written (TitleLink, true); -- test for accept-this-as-written markup
if (not accept_link) and utilities.in_array (TitleLink, {'none', 'pmc', 'doi'}) then -- check for special keywords
auto_select = TitleLink; -- remember selection for later
TitleLink = ''; -- treat as if |title-link= would have been empty
end
TitleLink = link_title_ok (TitleLink, A:ORIGIN ('TitleLink'), Title, 'title'); -- check for wiki-markup in |title-link= or wiki-markup in |title= when |title-link= is set
local Section = ''; -- {{cite map}} only; preset to empty string for concatenation if not used
if 'map' == config.CitationClass and 'section' == Chapter_origin then
Section = A['Chapter']; -- get |section= from |chapter= alias list; |chapter= and the other aliases not supported in {{cite map}}
Chapter = ''; -- unset for now; will be reset later from |map= if present
end
local Periodical = A['Periodical'];
local Periodical_origin = A:ORIGIN('Periodical');
local ScriptPeriodical = A['ScriptPeriodical'];
local ScriptPeriodical_origin = A:ORIGIN('ScriptPeriodical');
local TransPeriodical = A['TransPeriodical'];
local TransPeriodical_origin = A:ORIGIN ('TransPeriodical');
if (utilities.in_array (config.CitationClass, {'book', 'encyclopaedia'}) and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical) or utilities.is_set (TransPeriodical))) then
local param;
if utilities.is_set (Periodical) then -- get a parameter name from one of these periodical related meta-parameters
Periodical = ''; -- unset because not valid {{cite book}} or {{cite encyclopedia}} parameters
param = Periodical_origin -- get parameter name for error messaging
elseif utilities.is_set (TransPeriodical) then
TransPeriodical = ''; -- unset because not valid {{cite book}} or {{cite encyclopedia}} parameters
param = TransPeriodical_origin; -- get parameter name for error messaging
elseif utilities.is_set (ScriptPeriodical) then
ScriptPeriodical = ''; -- unset because not valid {{cite book}} or {{cite encyclopedia}} parameters
param = ScriptPeriodical_origin; -- get parameter name for error messaging
end
if utilities.is_set (param) then -- if we found one
utilities.set_message ('err_periodical_ignored', {param}); -- emit an error message
end
end
if utilities.is_set (Periodical) then
local i;
Periodical, i = utilities.strip_apostrophe_markup (Periodical); -- strip apostrophe markup so that metadata isn't contaminated
if i then -- non-zero when markup was stripped so emit an error message
utilities.set_message ('err_apostrophe_markup', {Periodical_origin});
end
end
if 'mailinglist' == config.CitationClass then -- special case for {{cite mailing list}}
if utilities.is_set (Periodical) and utilities.is_set (A ['MailingList']) then -- both set emit an error TODO: make a function for this and similar?
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', Periodical_origin) .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'mailinglist')});
end
Periodical = A ['MailingList']; -- error or no, set Periodical to |mailinglist= value because this template is {{cite mailing list}}
Periodical_origin = A:ORIGIN('MailingList');
end
-- web and news not tested for now because of
-- Wikipedia:Administrators%27_noticeboard#Is_there_a_semi-automated_tool_that_could_fix_these_annoying_"Cite_Web"_errors?
if not (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) then -- 'periodical' templates require periodical parameter
-- local p = {['journal'] = 'journal', ['magazine'] = 'magazine', ['news'] = 'newspaper', ['web'] = 'website'}; -- for error message
local p = {['journal'] = 'journal', ['magazine'] = 'magazine'}; -- for error message
if p[config.CitationClass] then
utilities.set_message ('err_missing_periodical', {config.CitationClass, p[config.CitationClass]});
end
end
local Volume;
if 'citation' == config.CitationClass then
if utilities.is_set (Periodical) then
if not utilities.in_array (Periodical_origin, cfg.citation_no_volume_t) then -- {{citation}} does not render |volume= when these parameters are used
Volume = A['Volume']; -- but does for all other 'periodicals'
end
elseif utilities.is_set (ScriptPeriodical) then
if 'script-website' ~= ScriptPeriodical_origin then -- {{citation}} does not render volume for |script-website=
Volume = A['Volume']; -- but does for all other 'periodicals'
end
else
Volume = A['Volume']; -- and does for non-'periodical' cites
end
elseif utilities.in_array (config.CitationClass, cfg.templates_using_volume) then -- render |volume= for cs1 according to the configuration settings
Volume = A['Volume'];
end
extra_text_in_vol_iss_check (Volume, A:ORIGIN ('Volume'), 'v');
local Issue;
if 'citation' == config.CitationClass then
if utilities.is_set (Periodical) and utilities.in_array (Periodical_origin, cfg.citation_issue_t) then -- {{citation}} may render |issue= when these parameters are used
Issue = utilities.hyphen_to_dash (A['Issue']);
end
elseif utilities.in_array (config.CitationClass, cfg.templates_using_issue) then -- conference & map books do not support issue; {{citation}} listed here because included in settings table
if not (utilities.in_array (config.CitationClass, {'conference', 'map', 'citation'}) and not (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical))) then
Issue = utilities.hyphen_to_dash (A['Issue']);
end
end
local ArticleNumber;
if utilities.in_array (config.CitationClass, {'journal', 'conference'}) or ('citation' == config.CitationClass and utilities.is_set (Periodical) and 'journal' == Periodical_origin) then
ArticleNumber = A['ArticleNumber'];
end
extra_text_in_vol_iss_check (Issue, A:ORIGIN ('Issue'), 'i');
local Page;
local Pages;
local At;
local QuotePage;
local QuotePages;
if not utilities.in_array (config.CitationClass, cfg.templates_not_using_page) then -- TODO: rewrite to emit ignored parameter error message?
Page = A['Page'];
Pages = utilities.hyphen_to_dash (A['Pages']);
At = A['At'];
QuotePage = A['QuotePage'];
QuotePages = utilities.hyphen_to_dash (A['QuotePages']);
end
local Edition = A['Edition'];
local PublicationPlace = place_check (A['PublicationPlace'], A:ORIGIN('PublicationPlace'));
local Place = place_check (A['Place'], A:ORIGIN('Place'));
local PublisherName = A['PublisherName'];
local PublisherName_origin = A:ORIGIN('PublisherName');
if utilities.is_set (PublisherName) and (cfg.keywords_xlate['none'] ~= PublisherName) then
local i = 0;
PublisherName, i = utilities.strip_apostrophe_markup (PublisherName); -- strip apostrophe markup so that metadata isn't contaminated; publisher is never italicized
if i and (0 < i) then -- non-zero when markup was stripped so emit an error message
utilities.set_message ('err_apostrophe_markup', {PublisherName_origin});
end
end
if ('document' == config.CitationClass) and not utilities.is_set (PublisherName) then
utilities.set_message ('err_missing_publisher', {config.CitationClass, 'publisher'});
end
local Newsgroup = A['Newsgroup']; -- TODO: strip apostrophe markup?
local Newsgroup_origin = A:ORIGIN('Newsgroup');
if 'newsgroup' == config.CitationClass then
if utilities.is_set (PublisherName) and (cfg.keywords_xlate['none'] ~= PublisherName) then -- general use parameter |publisher= not allowed in cite newsgroup
utilities.set_message ('err_parameter_ignored', {PublisherName_origin});
end
PublisherName = nil; -- ensure that this parameter is unset for the time being; will be used again after COinS
end
local URL = A['URL']; -- TODO: better way to do this for URL, ChapterURL, and MapURL?
local UrlAccess = is_valid_parameter_value (A['UrlAccess'], A:ORIGIN('UrlAccess'), cfg.keywords_lists['url-access'], nil);
if not utilities.is_set (URL) and utilities.is_set (UrlAccess) then
UrlAccess = nil;
utilities.set_message ('err_param_access_requires_param', 'url');
end
local ChapterURL = A['ChapterURL'];
local ChapterUrlAccess = is_valid_parameter_value (A['ChapterUrlAccess'], A:ORIGIN('ChapterUrlAccess'), cfg.keywords_lists['url-access'], nil);
if not utilities.is_set (ChapterURL) and utilities.is_set (ChapterUrlAccess) then
ChapterUrlAccess = nil;
utilities.set_message ('err_param_access_requires_param', {A:ORIGIN('ChapterUrlAccess'):gsub ('%-access', '')});
end
local MapUrlAccess = is_valid_parameter_value (A['MapUrlAccess'], A:ORIGIN('MapUrlAccess'), cfg.keywords_lists['url-access'], nil);
if not utilities.is_set (A['MapURL']) and utilities.is_set (MapUrlAccess) then
MapUrlAccess = nil;
utilities.set_message ('err_param_access_requires_param', {'map-url'});
end
local this_page = mw.title.getCurrentTitle(); -- also used for COinS and for language
local no_tracking_cats = is_valid_parameter_value (A['NoTracking'], A:ORIGIN('NoTracking'), cfg.keywords_lists['yes_true_y'], nil);
-- check this page to see if it is in one of the namespaces that cs1 is not supposed to add to the error categories
if not utilities.is_set (no_tracking_cats) then -- ignore if we are already not going to categorize this page
if cfg.uncategorized_namespaces[this_page.namespace] then -- is this page's namespace id one of the uncategorized namespace ids?
no_tracking_cats = "true"; -- set no_tracking_cats
end
for _, v in ipairs (cfg.uncategorized_subpages) do -- cycle through page name patterns
if this_page.text:match (v) then -- test page name against each pattern
no_tracking_cats = "true"; -- set no_tracking_cats
break; -- bail out if one is found
end
end
end
-- no_tracking_cats = "true"; -- выключаем всю категоризацию для РУВИКИ
-- check for extra |page=, |pages= or |at= parameters. (also sheet and sheets while we're at it)
utilities.select_one (args, {'page', 'p', 'pp', 'pages', 'at', 'sheet', 'sheets'}, 'err_redundant_parameters'); -- this is a dummy call simply to get the error message and category
local coins_pages;
Page, Pages, At, coins_pages = insource_loc_get (Page, A:ORIGIN('Page'), Pages, A:ORIGIN('Pages'), At);
local NoPP = is_valid_parameter_value (A['NoPP'], A:ORIGIN('NoPP'), cfg.keywords_lists['yes_true_y'], nil);
if utilities.is_set (PublicationPlace) and utilities.is_set (Place) then -- both |publication-place= and |place= (|location=) allowed if different
utilities.add_prop_cat ('location-test'); -- add property cat to evaluate how often PublicationPlace and Place are used together
if PublicationPlace == Place then
Place = ''; -- unset; don't need both if they are the same
end
elseif not utilities.is_set (PublicationPlace) and utilities.is_set (Place) then -- when only |place= (|location=) is set ...
PublicationPlace = Place; -- promote |place= (|location=) to |publication-place
end
if PublicationPlace == Place then Place = ''; end -- don't need both if they are the same
local URL_origin = A:ORIGIN('URL'); -- get name of parameter that holds URL
local ChapterURL_origin = A:ORIGIN('ChapterURL'); -- get name of parameter that holds ChapterURL
local ScriptChapter = A['ScriptChapter'];
local ScriptChapter_origin = A:ORIGIN ('ScriptChapter');
local Format = A['Format'];
local ChapterFormat = A['ChapterFormat'];
local TransChapter = A['TransChapter'];
local TransChapter_origin = A:ORIGIN ('TransChapter');
local TransTitle = A['TransTitle'];
local ScriptTitle = A['ScriptTitle'];
--[[
Parameter remapping for cite encyclopedia:
When the citation has these parameters:
|encyclopedia= and |title= then map |title= to |article= and |encyclopedia= to |title= for rendering
|encyclopedia= and |article= then map |encyclopedia= to |title= for rendering
|trans-title= maps to |trans-chapter= when |title= is re-mapped
|url= maps to |chapter-url= when |title= is remapped
All other combinations of |encyclopedia=, |title=, and |article= are not modified
]]
local Encyclopedia = A['Encyclopedia']; -- used as a flag by this module and by ~/COinS
local ScriptEncyclopedia = A['ScriptEncyclopedia'];
local TransEncyclopedia = A['TransEncyclopedia'];
if utilities.is_set (Encyclopedia) or utilities.is_set (ScriptEncyclopedia) then -- emit error message when Encyclopedia set but template is other than {{cite encyclopedia}} or {{citation}}
if 'encyclopaedia' ~= config.CitationClass and 'citation' ~= config.CitationClass then
if utilities.is_set (Encyclopedia) then
utilities.set_message ('err_parameter_ignored', {A:ORIGIN ('Encyclopedia')});
else
utilities.set_message ('err_parameter_ignored', {A:ORIGIN ('ScriptEncyclopedia')});
end
Encyclopedia = nil; -- unset these because not supported by this template
ScriptEncyclopedia = nil;
TransEncyclopedia = nil;
end
elseif utilities.is_set (TransEncyclopedia) then
utilities.set_message ('err_trans_missing_title', {'encyclopedia'});
end
if ('encyclopaedia' == config.CitationClass) or ('citation' == config.CitationClass and utilities.is_set (Encyclopedia)) then
if utilities.is_set (Periodical) and utilities.is_set (Encyclopedia) then -- when both parameters set emit an error message; {{citation}} only; Periodical not allowed in {{cite encyclopedia}}
utilities.set_message ('err_periodical_ignored', {Periodical_origin});
end
if utilities.is_set (Encyclopedia) or utilities.is_set (ScriptEncyclopedia) then
Periodical = Encyclopedia; -- error or no, set Periodical to Encyclopedia for rendering; {{citation}} could (not legitimately) have both; use Encyclopedia
Periodical_origin = A:ORIGIN ('Encyclopedia');
ScriptPeriodical = ScriptEncyclopedia;
ScriptPeriodical_origin = A:ORIGIN ('ScriptEncyclopedia');
if utilities.is_set (Title) or utilities.is_set (ScriptTitle) then
if not utilities.is_set (Chapter) then
Chapter = Title; -- |encyclopedia= and |title= are set so map |title= params to |article= params for rendering
ScriptChapter = ScriptTitle;
ScriptChapter_origin = A:ORIGIN('ScriptTitle')
TransChapter = TransTitle;
ChapterURL = URL;
ChapterURL_origin = URL_origin;
ChapterUrlAccess = UrlAccess;
ChapterFormat = Format;
if not utilities.is_set (ChapterURL) and utilities.is_set (TitleLink) then
Chapter = utilities.make_wikilink (TitleLink, Chapter);
end
Title = Periodical; -- now map |encyclopedia= params to |title= params for rendering
ScriptTitle = ScriptPeriodical or '';
TransTitle = TransEncyclopedia or '';
Periodical = ''; -- redundant so unset
ScriptPeriodical = '';
URL = '';
Format = '';
TitleLink = '';
end
elseif utilities.is_set (Chapter) or utilities.is_set (ScriptChapter) then -- |title= not set
Title = Periodical; -- |encyclopedia= set and |article= set so map |encyclopedia= to |title= for rendering
ScriptTitle = ScriptPeriodical or '';
TransTitle = TransEncyclopedia or '';
Periodical = ''; -- redundant so unset
ScriptPeriodical = '';
end
end
end
-- special case for cite techreport.
local ID = A['ID'];
if (config.CitationClass == "techreport") then -- special case for cite techreport
if utilities.is_set (A['Number']) then -- cite techreport uses 'number', which other citations alias to 'issue'
if not utilities.is_set (ID) then -- can we use ID for the "number"?
ID = A['Number']; -- yes, use it
else -- ID has a value so emit error message
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'id') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'number')});
end
end
end
-- Account for the oddity that is {{cite conference}}, before generation of COinS data.
local ChapterLink -- = A['ChapterLink']; -- deprecated as a parameter but still used internally by cite episode
local Conference = A['Conference'];
local BookTitle = A['BookTitle'];
local TransTitle_origin = A:ORIGIN ('TransTitle');
if 'conference' == config.CitationClass then
if utilities.is_set (BookTitle) then
Chapter = Title;
Chapter_origin = 'title';
-- ChapterLink = TitleLink; -- |chapter-link= is deprecated
ChapterURL = URL;
ChapterUrlAccess = UrlAccess;
ChapterURL_origin = URL_origin;
URL_origin = '';
ChapterFormat = Format;
TransChapter = TransTitle;
TransChapter_origin = TransTitle_origin;
Title = BookTitle;
Format = '';
-- TitleLink = '';
TransTitle = '';
URL = '';
end
elseif 'speech' ~= config.CitationClass then
Conference = ''; -- not cite conference or cite speech so make sure this is empty string
end
-- CS1/2 mode
local Mode;
if cfg.global_cs1_config_t['Mode'] then -- global setting in {{cs1 config}} overrides local |mode= parameter value; nil when empty or assigned value invalid
Mode = is_valid_parameter_value (cfg.global_cs1_config_t['Mode'], 'cs1 config: mode', cfg.keywords_lists['mode'], ''); -- error messaging 'param' here is a hoax
else
Mode = is_valid_parameter_value (A['Mode'], A:ORIGIN('Mode'), cfg.keywords_lists['mode'], '');
end
if cfg.global_cs1_config_t['Mode'] and utilities.is_set (A['Mode']) then -- when template has |mode=<something> which global setting has overridden
utilities.set_message ('maint_overridden_setting'); -- set a maint message
end
-- separator character and postscript
local sepc, PostScript = set_style (Mode:lower(), A['PostScript'], config.CitationClass);
-- controls capitalization of certain static text
local use_lowercase = ( sepc == ',' );
-- cite map oddities
local Cartography = "";
local Scale = "";
local Sheet = A['Sheet'] or '';
local Sheets = A['Sheets'] or '';
if config.CitationClass == "map" then
if utilities.is_set (Chapter) then --TODO: make a function for this and similar?
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'map') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', Chapter_origin)}); -- add error message
end
Chapter = A['Map'];
Chapter_origin = A:ORIGIN('Map');
ChapterURL = A['MapURL'];
ChapterURL_origin = A:ORIGIN('MapURL');
TransChapter = A['TransMap'];
ScriptChapter = A['ScriptMap']
ScriptChapter_origin = A:ORIGIN('ScriptMap')
ChapterUrlAccess = MapUrlAccess;
ChapterFormat = A['MapFormat'];
Cartography = A['Cartography'];
if utilities.is_set ( Cartography ) then
Cartography = sepc .. " " .. wrap_msg ('cartography', Cartography, use_lowercase);
end
Scale = A['Scale'];
if utilities.is_set ( Scale ) then
Scale = sepc .. " " .. Scale;
end
end
-- Account for the oddities that are {{cite episode}} and {{cite serial}}, before generation of COinS data.
local Series = A['Series'];
if 'episode' == config.CitationClass or 'serial' == config.CitationClass then
local SeriesLink = A['SeriesLink'];
SeriesLink = link_title_ok (SeriesLink, A:ORIGIN ('SeriesLink'), Series, 'series'); -- check for wiki-markup in |series-link= or wiki-markup in |series= when |series-link= is set
local Network = A['Network'];
local Station = A['Station'];
local s, n = {}, {};
-- do common parameters first
if utilities.is_set (Network) then table.insert(n, Network); end
if utilities.is_set (Station) then table.insert(n, Station); end
ID = table.concat(n, sepc .. ' ');
if 'episode' == config.CitationClass then -- handle the oddities that are strictly {{cite episode}}
local Season = A['Season'];
local SeriesNumber = A['SeriesNumber'];
if utilities.is_set (Season) and utilities.is_set (SeriesNumber) then -- these are mutually exclusive so if both are set TODO: make a function for this and similar?
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'season') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'seriesno')}); -- add error message
SeriesNumber = ''; -- unset; prefer |season= over |seriesno=
end
-- assemble a table of parts concatenated later into Series
if utilities.is_set (Season) then table.insert(s, wrap_msg ('season', Season, use_lowercase)); end
if utilities.is_set (SeriesNumber) then table.insert(s, wrap_msg ('seriesnum', SeriesNumber, use_lowercase)); end
if utilities.is_set (Issue) then table.insert(s, wrap_msg ('episode', Issue, use_lowercase)); end
Issue = ''; -- unset because this is not a unique parameter
Chapter = Title; -- promote title parameters to chapter
ScriptChapter = ScriptTitle;
ScriptChapter_origin = A:ORIGIN('ScriptTitle');
ChapterLink = TitleLink; -- alias |episode-link=
TransChapter = TransTitle;
ChapterURL = URL;
ChapterUrlAccess = UrlAccess;
ChapterURL_origin = URL_origin;
ChapterFormat = Format;
Title = Series; -- promote series to title
TitleLink = SeriesLink;
Series = table.concat(s, sepc .. ' '); -- this is concatenation of season, seriesno, episode number
if utilities.is_set (ChapterLink) and not utilities.is_set (ChapterURL) then -- link but not URL
Chapter = utilities.make_wikilink (ChapterLink, Chapter);
elseif utilities.is_set (ChapterLink) and utilities.is_set (ChapterURL) then -- if both are set, URL links episode;
Series = utilities.make_wikilink (ChapterLink, Series);
end
URL = ''; -- unset
TransTitle = '';
ScriptTitle = '';
Format = '';
else -- now oddities that are cite serial
Issue = ''; -- unset because this parameter no longer supported by the citation/core version of cite serial
Chapter = A['Episode']; -- TODO: make |episode= available to cite episode someday?
if utilities.is_set (Series) and utilities.is_set (SeriesLink) then
Series = utilities.make_wikilink (SeriesLink, Series);
end
Series = utilities.wrap_style ('italic-title', Series); -- series is italicized
end
end
-- end of {{cite episode}} stuff
-- handle type parameter for those CS1 citations that have default values
local TitleType = A['TitleType'];
local Degree = A['Degree'];
if utilities.in_array (config.CitationClass, {'AV-media-notes', 'document', 'interview', 'mailinglist', 'map', 'podcast', 'pressrelease', 'report', 'speech', 'techreport', 'thesis'}) then
TitleType = set_titletype (config.CitationClass, TitleType);
if utilities.is_set (Degree) and "Thesis" == TitleType then -- special case for cite thesis
TitleType = Degree .. ' ' .. cfg.title_types ['thesis']:lower();
end
end
if utilities.is_set (TitleType) then -- if type parameter is specified
TitleType = utilities.substitute ( cfg.messages['type'], TitleType); -- display it in parentheses
-- TODO: Hack on TitleType to fix bunched parentheses problem
end
-- legacy: promote PublicationDate to Date if neither Date nor Year are set.
local Date = A['Date'];
local Date_origin; -- to hold the name of parameter promoted to Date; required for date error messaging
local PublicationDate = A['PublicationDate'];
local Year = A['Year'];
if not utilities.is_set (Date) then
Date = Year; -- promote Year to Date
Year = nil; -- make nil so Year as empty string isn't used for CITEREF
if not utilities.is_set (Date) and utilities.is_set (PublicationDate) then -- use PublicationDate when |date= and |year= are not set
Date = PublicationDate; -- promote PublicationDate to Date
PublicationDate = ''; -- unset, no longer needed
Date_origin = A:ORIGIN('PublicationDate'); -- save the name of the promoted parameter
else
Date_origin = A:ORIGIN('Year'); -- save the name of the promoted parameter
end
else
Date_origin = A:ORIGIN('Date'); -- not a promotion; name required for error messaging
end
if PublicationDate == Date then PublicationDate = ''; end -- if PublicationDate is same as Date, don't display in rendered citation
--[[
Go test all of the date-holding parameters for valid MOS:DATE format and make sure that dates are real dates. This must be done before we do COinS because here is where
we get the date used in the metadata.
Date validation supporting code is in Module:Citation/CS1/Date_validation
]]
local DF = is_valid_parameter_value (A['DF'], A:ORIGIN('DF'), cfg.keywords_lists['df'], '');
if not utilities.is_set (DF) then
DF = cfg.global_df; -- local |df= if present overrides global df set by {{use xxx date}} template
end
local ArchiveURL;
local ArchiveDate;
local ArchiveFormat = A['ArchiveFormat'];
local archive_url_timestamp; -- timestamp from wayback machine url
ArchiveURL, ArchiveDate, archive_url_timestamp = archive_url_check (A['ArchiveURL'], A['ArchiveDate'])
ArchiveFormat = style_format (ArchiveFormat, ArchiveURL, 'archive-format', 'archive-url');
ArchiveURL, ArchiveDate = is_unique_archive_url (ArchiveURL, URL, ChapterURL, A:ORIGIN('ArchiveURL'), ArchiveDate); -- add error message when URL or ChapterURL == ArchiveURL
local AccessDate = A['AccessDate'];
local COinS_date = {}; -- holds date info extracted from |date= for the COinS metadata by Module:Date verification
local DoiBroken = A['DoiBroken'];
local Embargo = A['Embargo'];
local anchor_year; -- used in the CITEREF identifier
do -- create defined block to contain local variables error_message, date_parameters_list, mismatch
local error_message = '';
-- AirDate has been promoted to Date so not necessary to check it
local date_parameters_list = {
['access-date'] = {val = AccessDate, name = A:ORIGIN ('AccessDate')},
['archive-date'] = {val = ArchiveDate, name = A:ORIGIN ('ArchiveDate')},
['date'] = {val = Date, name = Date_origin},
['doi-broken-date'] = {val = DoiBroken, name = A:ORIGIN ('DoiBroken')},
['pmc-embargo-date'] = {val = Embargo, name = A:ORIGIN ('Embargo')},
['publication-date'] = {val = PublicationDate, name = A:ORIGIN ('PublicationDate')},
['year'] = {val = Year, name = A:ORIGIN ('Year')},
};
local error_list = {};
anchor_year, Embargo = validation.dates(date_parameters_list, COinS_date, error_list);
if utilities.is_set (Year) and utilities.is_set (Date) then -- both |date= and |year= not normally needed;
validation.year_date_check (Year, A:ORIGIN ('Year'), Date, A:ORIGIN ('Date'), error_list);
end
if 0 == #error_list then -- error free dates only; 0 when error_list is empty
local modified = false; -- flag
if utilities.is_set (DF) then -- if we need to reformat dates
modified = validation.reformat_dates (date_parameters_list, DF); -- reformat to DF format, use long month names if appropriate
end
if true == validation.date_hyphen_to_dash (date_parameters_list) then -- convert hyphens to dashes where appropriate
modified = true;
utilities.set_message ('maint_date_format'); -- hyphens were converted so add maint category
end
-- for those wikis that can and want to have English date names translated to the local language; not supported at en.wiki
if cfg.date_name_auto_xlate_enable and validation.date_name_xlate (date_parameters_list, cfg.date_digit_auto_xlate_enable ) then
utilities.set_message ('maint_date_auto_xlated'); -- add maint cat
modified = true;
end
if modified then -- if the date_parameters_list values were modified
AccessDate = date_parameters_list['access-date'].val; -- overwrite date holding parameters with modified values
ArchiveDate = date_parameters_list['archive-date'].val;
Date = date_parameters_list['date'].val;
DoiBroken = date_parameters_list['doi-broken-date'].val;
PublicationDate = date_parameters_list['publication-date'].val;
end
if archive_url_timestamp and utilities.is_set (ArchiveDate) then
validation.archive_date_check (ArchiveDate, archive_url_timestamp, DF); -- does YYYYMMDD in archive_url_timestamp match date in ArchiveDate
end
else
utilities.set_message ('err_bad_date', {utilities.make_sep_list (#error_list, error_list)}); -- add this error message
end
end -- end of do
if utilities.in_array (config.CitationClass, {'book', 'encyclopaedia'}) or -- {{cite book}}, {{cite encyclopedia}}; TODO: {{cite conference}} and others?
('citation' == config.CitationClass and utilities.is_set (Encyclopedia)) or -- {{citation}} as an encylopedia citation
('citation' == config.CitationClass and not utilities.is_set (Periodical)) then -- {{citation}} as a book citation
if utilities.is_set (PublicationPlace) then
if not utilities.is_set (PublisherName) then
local date = COinS_date.rftdate and tonumber (COinS_date.rftdate:match ('%d%d%d%d')); -- get year portion of COinS date (because in Arabic numerals); convert string to number
if date and (1850 <= date) then -- location has no publisher; if date is 1850 or later
utilities.set_message ('maint_location_no_publisher'); -- add maint cat
end
else -- PublisherName has a value
if cfg.keywords_xlate['none'] == PublisherName then -- if that value is 'none' (only for book and encyclopedia citations)
PublisherName = ''; -- unset
end
end
end
end
local ID_list = {}; -- sequence table of rendered identifiers
local ID_list_coins = {}; -- table of identifiers and their values from args; key is same as cfg.id_handlers's key
local Class = A['Class']; -- arxiv class identifier
local ID_support = {
{A['ASINTLD'], 'ASIN', 'err_asintld_missing_asin', A:ORIGIN ('ASINTLD')},
{DoiBroken, 'DOI', 'err_doibroken_missing_doi', A:ORIGIN ('DoiBroken')},
{Embargo, 'PMC', 'err_embargo_missing_pmc', A:ORIGIN ('Embargo')},
}
ID_list, ID_list_coins = identifiers.identifier_lists_get (args, {DoiBroken = DoiBroken, ASINTLD = A['ASINTLD'], Embargo = Embargo, Class = Class}, ID_support);
-- Account for the oddities that are {{cite arxiv}}, {{cite biorxiv}}, {{cite citeseerx}}, {{cite medrxiv}}, {{cite ssrn}}, before generation of COinS data.
if utilities.in_array (config.CitationClass, whitelist.preprint_template_list_t) then -- |arxiv= or |eprint= required for cite arxiv; |biorxiv=, |citeseerx=, |medrxiv=, |ssrn= required for their templates
if not (args[cfg.id_handlers[config.CitationClass:upper()].parameters[1]] or -- can't use ID_list_coins k/v table here because invalid parameters omitted
args[cfg.id_handlers[config.CitationClass:upper()].parameters[2]]) then -- which causes unexpected parameter missing error message
utilities.set_message ('err_' .. config.CitationClass .. '_missing'); -- add error message
end
Periodical = ({['arxiv'] = 'arXiv', ['biorxiv'] = 'bioRxiv', ['citeseerx'] = 'CiteSeerX', ['medrxiv'] = 'medRxiv', ['ssrn'] = 'Social Science Research Network'})[config.CitationClass];
end
-- Link the title of the work if no |url= was provided, but we have a |pmc= or a |doi= with |doi-access=free
if config.CitationClass == "journal" and not utilities.is_set (URL) and not utilities.is_set (TitleLink) and not utilities.in_array (cfg.keywords_xlate[Title], {'off', 'none'}) then -- TODO: remove 'none' once existing citations have been switched to 'off', so 'none' can be used as token for "no title" instead
if 'none' ~= cfg.keywords_xlate[auto_select] then -- if auto-linking not disabled
if identifiers.auto_link_urls[auto_select] then -- manual selection
URL = identifiers.auto_link_urls[auto_select]; -- set URL to be the same as identifier's external link
URL_origin = cfg.id_handlers[auto_select:upper()].parameters[1]; -- set URL_origin to parameter name for use in error message if citation is missing a |title=
elseif identifiers.auto_link_urls['pmc'] then -- auto-select PMC
URL = identifiers.auto_link_urls['pmc']; -- set URL to be the same as the PMC external link if not embargoed
URL_origin = cfg.id_handlers['PMC'].parameters[1]; -- set URL_origin to parameter name for use in error message if citation is missing a |title=
elseif identifiers.auto_link_urls['doi'] then -- auto-select DOI
URL = identifiers.auto_link_urls['doi'];
URL_origin = cfg.id_handlers['DOI'].parameters[1];
end
end
if utilities.is_set (URL) then -- set when using an identifier-created URL
if utilities.is_set (AccessDate) then -- |access-date= requires |url=; identifier-created URL is not |url=
utilities.set_message ('err_accessdate_missing_url'); -- add an error message
AccessDate = ''; -- unset
end
if utilities.is_set (ArchiveURL) then -- |archive-url= requires |url=; identifier-created URL is not |url=
utilities.set_message ('err_archive_missing_url'); -- add an error message
ArchiveURL = ''; -- unset
end
end
end
-- At this point fields may be nil if they weren't specified in the template use. We can use that fact.
-- Test if citation has no title
if not utilities.is_set (Title) and not utilities.is_set (TransTitle) and not utilities.is_set (ScriptTitle) then -- has special case for cite episode
utilities.set_message ('err_citation_missing_title', {'episode' == config.CitationClass and 'series' or 'title'});
end
if utilities.in_array (cfg.keywords_xlate[Title], {'off', 'none'}) and
utilities.in_array (config.CitationClass, {'journal', 'citation'}) and
(utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and
('journal' == Periodical_origin or 'script-journal' == ScriptPeriodical_origin) then -- special case for journal cites
Title = ''; -- set title to empty string
utilities.set_message ('maint_untitled'); -- add maint cat
end
-- COinS metadata (see <http://ocoins.info/>) for automated parsing of citation information.
-- handle the oddity that is cite encyclopedia and {{citation |encyclopedia=something}}. Here we presume that
-- when Periodical, Title, and Chapter are all set, then Periodical is the book (encyclopedia) title, Title
-- is the article title, and Chapter is a section within the article. So, we remap
local coins_chapter = Chapter; -- default assuming that remapping not required
local coins_title = Title; -- et tu
if 'encyclopaedia' == config.CitationClass or ('citation' == config.CitationClass and utilities.is_set (Encyclopedia)) then
if utilities.is_set (Chapter) and utilities.is_set (Title) and utilities.is_set (Periodical) then -- if all are used then
coins_chapter = Title; -- remap
coins_title = Periodical;
end
end
local coins_author = a; -- default for coins rft.au
if 0 < #c then -- but if contributor list
coins_author = c; -- use that instead
end
-- this is the function call to COinS()
local OCinSoutput = metadata.COinS({
['Periodical'] = utilities.strip_apostrophe_markup (Periodical), -- no markup in the metadata
['Encyclopedia'] = Encyclopedia, -- just a flag; content ignored by ~/COinS
['Chapter'] = metadata.make_coins_title (coins_chapter, ScriptChapter), -- Chapter and ScriptChapter stripped of bold / italic / accept-as-written markup
['Degree'] = Degree; -- cite thesis only
['Title'] = metadata.make_coins_title (coins_title, ScriptTitle), -- Title and ScriptTitle stripped of bold / italic / accept-as-written markup
['PublicationPlace'] = PublicationPlace,
['Date'] = COinS_date.rftdate, -- COinS_date.* has correctly formatted date values if Date is valid;
['Season'] = COinS_date.rftssn,
['Quarter'] = COinS_date.rftquarter,
['Chron'] = COinS_date.rftchron,
['Series'] = Series,
['Volume'] = Volume,
['Issue'] = Issue,
['ArticleNumber'] = ArticleNumber,
['Pages'] = coins_pages or metadata.get_coins_pages (first_set ({Sheet, Sheets, Page, Pages, At, QuotePage, QuotePages}, 7)), -- pages stripped of external links
['Edition'] = Edition,
['PublisherName'] = PublisherName or Newsgroup, -- any apostrophe markup already removed from PublisherName
['URL'] = first_set ({ChapterURL, URL}, 2),
['Authors'] = coins_author,
['ID_list'] = ID_list_coins,
['RawPage'] = this_page.prefixedText,
}, config.CitationClass);
-- Account for the oddities that are {{cite arxiv}}, {{cite biorxiv}}, {{cite citeseerx}}, {{cite medrxiv}}, and {{cite ssrn}} AFTER generation of COinS data.
if utilities.in_array (config.CitationClass, whitelist.preprint_template_list_t) then -- we have set rft.jtitle in COinS to arXiv, bioRxiv, CiteSeerX, medRxiv, or ssrn now unset so it isn't displayed
Periodical = ''; -- periodical not allowed in these templates; if article has been published, use cite journal
end
-- special case for cite newsgroup. Do this after COinS because we are modifying Publishername to include some static text
if 'newsgroup' == config.CitationClass and utilities.is_set (Newsgroup) then
PublisherName = utilities.substitute (cfg.messages['newsgroup'], external_link( 'news:' .. Newsgroup, Newsgroup, Newsgroup_origin, nil ));
end
local Editors;
local EditorCount; -- used only for choosing {ed.) or (eds.) annotation at end of editor name-list
local Contributors; -- assembled contributors name list
local contributor_etal;
local Translators; -- assembled translators name list
local translator_etal;
local t = {}; -- translators list from |translator-lastn= / translator-firstn= pairs
t = extract_names (args, 'TranslatorList'); -- fetch translator list from |translatorn= / |translator-lastn=, -firstn=, -linkn=, -maskn=
local Interviewers;
local interviewers_list = {};
interviewers_list = extract_names (args, 'InterviewerList'); -- process preferred interviewers parameters
local interviewer_etal;
-- Now perform various field substitutions.
-- We also add leading spaces and surrounding markup and punctuation to the
-- various parts of the citation, but only when they are non-nil.
do
local last_first_list;
local control = {
format = NameListStyle, -- empty string, '&', 'amp', 'and', or 'vanc'
maximum = nil, -- as if display-authors or display-editors not set
mode = Mode
};
do -- do editor name list first because the now unsupported coauthors used to modify control table
local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayEditors'], A['DisplayEditors'], A:ORIGIN ('DisplayEditors'), #e);
control.maximum, editor_etal = get_display_names (display_names, #e, 'editors', editor_etal, param);
Editors, EditorCount = list_people (control, e, editor_etal);
if 1 == EditorCount and (true == editor_etal or 1 < #e) then -- only one editor displayed but includes etal then
EditorCount = 2; -- spoof to display (eds.) annotation
end
end
do -- now do interviewers
local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayInterviewers'], A['DisplayInterviewers'], A:ORIGIN ('DisplayInterviewers'), #interviewers_list);
control.maximum, interviewer_etal = get_display_names (display_names, #interviewers_list, 'interviewers', interviewer_etal, param);
Interviewers = list_people (control, interviewers_list, interviewer_etal);
end
do -- now do translators
local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayTranslators'], A['DisplayTranslators'], A:ORIGIN ('DisplayTranslators'), #t);
control.maximum, translator_etal = get_display_names (display_names, #t, 'translators', translator_etal, param);
Translators = list_people (control, t, translator_etal);
end
do -- now do contributors
local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayContributors'], A['DisplayContributors'], A:ORIGIN ('DisplayContributors'), #c);
control.maximum, contributor_etal = get_display_names (display_names, #c, 'contributors', contributor_etal, param);
Contributors = list_people (control, c, contributor_etal);
end
do -- now do authors
local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayAuthors'], A['DisplayAuthors'], A:ORIGIN ('DisplayAuthors'), #a, author_etal);
control.maximum, author_etal = get_display_names (display_names, #a, 'authors', author_etal, param);
last_first_list = list_people (control, a, author_etal);
if utilities.is_set (Authors) then
Authors, author_etal = name_has_etal (Authors, author_etal, false, 'authors'); -- find and remove variations on et al.
if author_etal then
Authors = Authors .. ' ' .. cfg.messages['et al']; -- add et al. to authors parameter
end
else
Authors = last_first_list; -- either an author name list or an empty string
end
end -- end of do
if utilities.is_set (Authors) and utilities.is_set (Collaboration) then
Authors = Authors .. ' (' .. Collaboration .. ')'; -- add collaboration after et al.
end
end
local ConferenceFormat = A['ConferenceFormat'];
local ConferenceURL = A['ConferenceURL'];
ConferenceFormat = style_format (ConferenceFormat, ConferenceURL, 'conference-format', 'conference-url');
Format = style_format (Format, URL, 'format', 'url');
-- special case for chapter format so no error message or cat when chapter not supported
if not (utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'pressrelease', 'podcast', 'newsgroup', 'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn'}) or
('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not utilities.is_set (Encyclopedia))) then
ChapterFormat = style_format (ChapterFormat, ChapterURL, 'chapter-format', 'chapter-url');
end
if not utilities.is_set (URL) then
if utilities.in_array (config.CitationClass, {"web", "podcast", "mailinglist"}) or -- |url= required for cite web, cite podcast, and cite mailinglist
('citation' == config.CitationClass and ('website' == Periodical_origin or 'script-website' == ScriptPeriodical_origin)) then -- and required for {{citation}} with |website= or |script-website=
utilities.set_message ('err_cite_web_url');
end
-- do we have |accessdate= without either |url= or |chapter-url=?
if utilities.is_set (AccessDate) and not utilities.is_set (ChapterURL) then -- ChapterURL may be set when URL is not set;
utilities.set_message ('err_accessdate_missing_url');
AccessDate = '';
end
end
local UrlStatus = is_valid_parameter_value (A['UrlStatus'], A:ORIGIN('UrlStatus'), cfg.keywords_lists['url-status'], '');
local OriginalURL
local OriginalURL_origin
local OriginalFormat
local OriginalAccess;
UrlStatus = UrlStatus:lower(); -- used later when assembling archived text
if utilities.is_set ( ArchiveURL ) then
if utilities.is_set (ChapterURL) then -- if chapter-url= is set apply archive url to it
OriginalURL = ChapterURL; -- save copy of source chapter's url for archive text
OriginalURL_origin = ChapterURL_origin; -- name of |chapter-url= parameter for error messages
OriginalFormat = ChapterFormat; -- and original |chapter-format=
if utilities.in_array (UrlStatus, {'unfit', 'deviated', 'dead', 'usurped', 'bot: unknown'}) then
ChapterURL = ArchiveURL -- swap-in the archive's URL
ChapterURL_origin = A:ORIGIN('ArchiveURL') -- name of |archive-url= parameter for error messages
ChapterFormat = ArchiveFormat or ''; -- swap in archive's format
ChapterUrlAccess = nil; -- restricted access levels do not make sense for archived URLs
end
elseif utilities.is_set (URL) then
OriginalURL = URL; -- save copy of original source URL
OriginalURL_origin = URL_origin; -- name of URL parameter for error messages
OriginalFormat = Format; -- and original |format=
OriginalAccess = UrlAccess;
if utilities.in_array (UrlStatus, {'unfit', 'deviated', 'dead', 'usurped', 'bot: unknown'}) then -- if URL set then |archive-url= applies to it
URL = ArchiveURL -- swap-in the archive's URL
URL_origin = A:ORIGIN('ArchiveURL') -- name of archive URL parameter for error messages
Format = ArchiveFormat or ''; -- swap in archive's format
UrlAccess = nil; -- restricted access levels do not make sense for archived URLs
end
end
elseif utilities.is_set (UrlStatus) then -- if |url-status= is set when |archive-url= is not set
utilities.set_message ('maint_url_status'); -- add maint cat
end
if utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'pressrelease', 'podcast', 'newsgroup', 'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn'}) or -- if any of the 'periodical' cites except encyclopedia
('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not utilities.is_set (Encyclopedia)) then
local chap_param;
if utilities.is_set (Chapter) then -- get a parameter name from one of these chapter related meta-parameters
chap_param = A:ORIGIN ('Chapter')
elseif utilities.is_set (TransChapter) then
chap_param = A:ORIGIN ('TransChapter')
elseif utilities.is_set (ChapterURL) then
chap_param = A:ORIGIN ('ChapterURL')
elseif utilities.is_set (ScriptChapter) then
chap_param = ScriptChapter_origin;
else utilities.is_set (ChapterFormat)
chap_param = A:ORIGIN ('ChapterFormat')
end
if utilities.is_set (chap_param) then -- if we found one
utilities.set_message ('err_chapter_ignored', {chap_param}); -- add error message
Chapter = ''; -- and set them to empty string to be safe with concatenation
TransChapter = '';
ChapterURL = '';
ScriptChapter = '';
ChapterFormat = '';
end
else -- otherwise, format chapter / article title
local no_quotes = false; -- default assume that we will be quoting the chapter parameter value
if utilities.is_set (Contribution) and 0 < #c then -- if this is a contribution with contributor(s)
if utilities.in_array (Contribution:lower(), cfg.keywords_lists.contribution) then -- and a generic contribution title
no_quotes = true; -- then render it unquoted
end
end
Chapter = format_chapter_title (ScriptChapter, ScriptChapter_origin, Chapter, Chapter_origin, TransChapter, TransChapter_origin, ChapterURL, ChapterURL_origin, no_quotes, ChapterUrlAccess); -- Contribution is also in Chapter
if utilities.is_set (Chapter) then
Chapter = Chapter .. ChapterFormat ;
if 'map' == config.CitationClass and utilities.is_set (TitleType) then
Chapter = Chapter .. ' ' .. TitleType; -- map annotation here; not after title
end
Chapter = Chapter .. sepc .. ' ';
elseif utilities.is_set (ChapterFormat) then -- |chapter= not set but |chapter-format= is so ...
Chapter = ChapterFormat .. sepc .. ' '; -- ... ChapterFormat has error message, we want to see it
end
end
-- Format main title
local plain_title = false;
local accept_title;
Title, accept_title = utilities.has_accept_as_written (Title, true); -- remove accept-this-as-written markup when it wraps all of <Title>
if accept_title and ('' == Title) then -- only support forced empty for now "(())"
Title = cfg.messages['notitle']; -- replace by predefined "No title" message
-- TODO: utilities.set_message ( 'err_redundant_parameters', ...); -- issue proper error message instead of muting
ScriptTitle = ''; -- just mute for now
TransTitle = ''; -- just mute for now
plain_title = true; -- suppress text decoration for descriptive title
utilities.set_message ('maint_untitled'); -- add maint cat
end
if not accept_title then -- <Title> not wrapped in accept-as-written markup
if '...' == Title:sub (-3) then -- if ellipsis is the last three characters of |title=
Title = Title:gsub ('(%.%.%.)%.+$', '%1'); -- limit the number of dots to three
elseif not mw.ustring.find (Title, '%.%s*%a%.$') and -- end of title is not a 'dot-(optional space-)letter-dot' initialism ...
not mw.ustring.find (Title, '%s+%a%.$') then -- ...and not a 'space-letter-dot' initial (''Allium canadense'' L.)
Title = mw.ustring.gsub(Title, '%' .. sepc .. '$', ''); -- remove any trailing separator character; sepc and ms.ustring() here for languages that use multibyte separator characters
end
if utilities.is_set (ArchiveURL) and is_archived_copy (Title) then
utilities.set_message ('maint_archived_copy'); -- add maintenance category before we modify the content of Title
end
if is_generic ('generic_titles', Title) then
utilities.set_message ('err_generic_title'); -- set an error message
end
end
if (not plain_title) and (utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'document', 'pressrelease', 'podcast', 'newsgroup', 'mailinglist', 'interview', 'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn'}) or
('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not utilities.is_set (Encyclopedia)) or
('map' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)))) then -- special case for cite map when the map is in a periodical treat as an article
Title = kern_quotes (Title); -- if necessary, separate title's leading and trailing quote marks from module provided quote marks
Title = utilities.wrap_style ('quoted-title', Title);
Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
TransTitle = utilities.wrap_style ('trans-quoted-title', TransTitle );
elseif plain_title or ('report' == config.CitationClass) then -- no styling for cite report and descriptive titles (otherwise same as above)
Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
TransTitle = utilities.wrap_style ('trans-quoted-title', TransTitle ); -- for cite report, use this form for trans-title
else
Title = utilities.wrap_style ('italic-title', Title);
Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
TransTitle = utilities.wrap_style ('trans-italic-title', TransTitle);
end
if utilities.is_set (TransTitle) then
if utilities.is_set (Title) then
TransTitle = " " .. TransTitle;
else
utilities.set_message ('err_trans_missing_title', {'title'});
end
end
if utilities.is_set (Title) then -- TODO: is this the right place to be making Wikisource URLs?
if utilities.is_set (TitleLink) and utilities.is_set (URL) then
utilities.set_message ('err_wikilink_in_url'); -- set an error message because we can't have both
TitleLink = ''; -- unset
end
if not utilities.is_set (TitleLink) and utilities.is_set (URL) then
Title = external_link (URL, Title, URL_origin, UrlAccess) .. TransTitle .. Format;
URL = ''; -- unset these because no longer needed
Format = "";
elseif utilities.is_set (TitleLink) and not utilities.is_set (URL) then
local ws_url;
ws_url = wikisource_url_make (TitleLink); -- ignore ws_label return; not used here
if ws_url then
Title = external_link (ws_url, Title .. ' ', 'ws link in title-link'); -- space char after Title to move icon away from italic text; TODO: a better way to do this?
Title = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], TitleLink, Title});
Title = Title .. TransTitle;
else
Title = utilities.make_wikilink (TitleLink, Title) .. TransTitle;
end
else
local ws_url, ws_label, L; -- Title has italic or quote markup by the time we get here which causes is_wikilink() to return 0 (not a wikilink)
ws_url, ws_label, L = wikisource_url_make (Title:gsub('^[\'"]*(.-)[\'"]*$', '%1')); -- make ws URL from |title= interwiki link (strip italic or quote markup); link portion L becomes tooltip label
if ws_url then
Title = Title:gsub ('%b[]', ws_label); -- replace interwiki link with ws_label to retain markup
Title = external_link (ws_url, Title .. ' ', 'ws link in title'); -- space char after Title to move icon away from italic text; TODO: a better way to do this?
Title = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, Title});
Title = Title .. TransTitle;
else
Title = Title .. TransTitle;
end
end
else
Title = TransTitle;
end
if utilities.is_set (Place) then
Place = " " .. wrap_msg ('written', Place, use_lowercase) .. sepc .. " ";
end
local ConferenceURL_origin = A:ORIGIN('ConferenceURL'); -- get name of parameter that holds ConferenceURL
if utilities.is_set (Conference) then
if utilities.is_set (ConferenceURL) then
Conference = external_link( ConferenceURL, Conference, ConferenceURL_origin, nil );
end
Conference = sepc .. " " .. Conference .. ConferenceFormat;
elseif utilities.is_set (ConferenceURL) then
Conference = sepc .. " " .. external_link( ConferenceURL, nil, ConferenceURL_origin, nil );
end
local Position = '';
if not utilities.is_set (Position) then
local Minutes = A['Minutes'];
local Time = A['Time'];
if utilities.is_set (Minutes) then
if utilities.is_set (Time) then --TODO: make a function for this and similar?
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'minutes') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'time')});
end
Position = " " .. Minutes .. " " .. cfg.messages['minutes'];
else
if utilities.is_set (Time) then
local TimeCaption = A['TimeCaption']
if not utilities.is_set (TimeCaption) then
TimeCaption = cfg.messages['event'];
if sepc ~= '.' then
TimeCaption = TimeCaption:lower();
end
end
Position = " " .. TimeCaption .. " " .. Time;
end
end
else
Position = " " .. Position;
At = '';
end
Page, Pages, Sheet, Sheets = format_pages_sheets (Page, Pages, Sheet, Sheets, config.CitationClass, Periodical_origin, sepc, NoPP, use_lowercase);
At = utilities.is_set (At) and (sepc .. " " .. At) or "";
Position = utilities.is_set (Position) and (sepc .. " " .. Position) or "";
if config.CitationClass == 'map' then
local Sections = A['Sections']; -- Section (singular) is an alias of Chapter so set earlier
local Inset = A['Inset'];
if utilities.is_set ( Inset ) then
Inset = sepc .. " " .. wrap_msg ('inset', Inset, use_lowercase);
end
if utilities.is_set ( Sections ) then
Section = sepc .. " " .. wrap_msg ('sections', Sections, use_lowercase);
elseif utilities.is_set ( Section ) then
Section = sepc .. " " .. wrap_msg ('section', Section, use_lowercase);
end
At = At .. Inset .. Section;
end
local Others = A['Others'];
if utilities.is_set (Others) and 0 == #a and 0 == #e then -- add maint cat when |others= has value and used without |author=, |editor=
if config.CitationClass == "AV-media-notes"
or config.CitationClass == "audio-visual" then -- special maint for AV/M which has a lot of 'false' positives right now
utilities.set_message ('maint_others_avm')
else
utilities.set_message ('maint_others');
end
end
Others = utilities.is_set (Others) and (sepc .. " " .. Others) or "";
if utilities.is_set (Translators) then
Others = safe_join ({sepc .. ' ', wrap_msg ('translated', Translators, use_lowercase), Others}, sepc);
end
if utilities.is_set (Interviewers) then
Others = safe_join ({sepc .. ' ', wrap_msg ('interview', Interviewers, use_lowercase), Others}, sepc);
end
local TitleNote = A['TitleNote'];
TitleNote = utilities.is_set (TitleNote) and (sepc .. " " .. TitleNote) or "";
if utilities.is_set (Edition) then
if Edition:match ('%f[%a][Ee]d%n?%.?$') or Edition:match ('%f[%a][Ee]dition$') then -- Ed, ed, Ed., ed., Edn, edn, Edn., edn.
utilities.set_message ('err_extra_text_edition'); -- add error message
end
Edition = " " .. wrap_msg ('edition', Edition);
else
Edition = '';
end
Series = utilities.is_set (Series) and wrap_msg ('series', {sepc, Series}) or ""; -- not the same as SeriesNum
local Agency = A['Agency'] or ''; -- |agency= only supported in {{cite news}}, {{cite press release}}, {{cite web}} and certain {{citation}} templates
if utilities.is_set (Agency) then -- this testing done here because {{citation}} supports 'news' citations
if utilities.in_array (config.CitationClass, {'news', 'pressrelease', 'web'}) or ('citation' == config.CitationClass and utilities.in_array (Periodical_origin, {"newspaper", "work"})) then
Agency = wrap_msg ('agency', {sepc, Agency}); -- format for rendering
else
Agency = ''; -- unset; not supported
utilities.set_message ('err_parameter_ignored', {'agency'}); -- add error message
end
end
Volume = format_volume_issue (Volume, Issue, ArticleNumber, config.CitationClass, Periodical_origin, sepc, use_lowercase);
if utilities.is_set (AccessDate) then
local retrv_text = " " .. cfg.messages['retrieved']
local status, result = pcall(formatDate, AccessDate) -- РУВИКИ: человекочитаемые даты
if status then
AccessDate = string.format("<span class='date'>%s</span>", result)
else
AccessDate = string.format("<span class='error'>(Строка «%s» не является верной датой, пожалуйста, укажите дату в формате <code>ГГГГ-ММ-ДД</code>)</span>", AccessDate)
end
-- AccessDate = nowrap_date (AccessDate); -- wrap in nowrap span if date in appropriate format
if (sepc ~= ".") then retrv_text = retrv_text:lower() end -- if mode is cs2, lower case
AccessDate = utilities.substitute (retrv_text, AccessDate); -- add retrieved text
AccessDate = utilities.substitute (cfg.presentation['accessdate'], {sepc, AccessDate}); -- allow editors to hide accessdates
end
if utilities.is_set (ID) then ID = sepc .. " " .. ID; end
local Docket = A['Docket'];
if "thesis" == config.CitationClass and utilities.is_set (Docket) then
ID = sepc .. " Docket " .. Docket .. ID;
end
if "report" == config.CitationClass and utilities.is_set (Docket) then -- for cite report when |docket= is set
ID = sepc .. ' ' .. Docket; -- overwrite ID even if |id= is set
end
if utilities.is_set (URL) then
URL = " " .. external_link( URL, nil, URL_origin, UrlAccess );
end
local Quote = A['Quote'];
local TransQuote = A['TransQuote'];
local ScriptQuote = A['ScriptQuote'];
if utilities.is_set (Quote) or utilities.is_set (TransQuote) or utilities.is_set (ScriptQuote) then
if utilities.is_set (Quote) then
if Quote:sub(1, 1) == '"' and Quote:sub(-1, -1) == '"' then -- if first and last characters of quote are quote marks
Quote = Quote:sub(2, -2); -- strip them off
end
end
Quote = kern_quotes (Quote); -- kern if needed
Quote = utilities.wrap_style ('quoted-text', Quote ); -- wrap in <q>...</q> tags
if utilities.is_set (ScriptQuote) then
Quote = script_concatenate (Quote, ScriptQuote, 'script-quote'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after quote is wrapped
end
if utilities.is_set (TransQuote) then
if TransQuote:sub(1, 1) == '"' and TransQuote:sub(-1, -1) == '"' then -- if first and last characters of |trans-quote are quote marks
TransQuote = TransQuote:sub(2, -2); -- strip them off
end
Quote = Quote .. " " .. utilities.wrap_style ('trans-quoted-title', TransQuote );
end
if utilities.is_set (QuotePage) or utilities.is_set (QuotePages) then -- add page prefix
local quote_prefix = '';
if utilities.is_set (QuotePage) then
extra_text_in_page_check (QuotePage, 'quote-page'); -- add to maint cat if |quote-page= value begins with what looks like p., pp., etc.
if not NoPP then
quote_prefix = utilities.substitute (cfg.messages['p-prefix'], {sepc, QuotePage}), '', '', '';
else
quote_prefix = utilities.substitute (cfg.messages['nopp'], {sepc, QuotePage}), '', '', '';
end
elseif utilities.is_set (QuotePages) then
extra_text_in_page_check (QuotePages, 'quote-pages'); -- add to maint cat if |quote-pages= value begins with what looks like p., pp., etc.
if tonumber(QuotePages) ~= nil and not NoPP then -- if only digits, assume single page
quote_prefix = utilities.substitute (cfg.messages['p-prefix'], {sepc, QuotePages}), '', '';
elseif not NoPP then
quote_prefix = utilities.substitute (cfg.messages['pp-prefix'], {sepc, QuotePages}), '', '';
else
quote_prefix = utilities.substitute (cfg.messages['nopp'], {sepc, QuotePages}), '', '';
end
end
Quote = quote_prefix .. ": " .. Quote;
else
Quote = sepc .. " " .. Quote;
end
PostScript = ""; -- cs1|2 does not supply terminal punctuation when |quote= is set
end
-- We check length of PostScript here because it will have been nuked by
-- the quote parameters. We'd otherwise emit a message even if there wasn't
-- a displayed postscript.
-- TODO: Should the max size (1) be configurable?
-- TODO: Should we check a specific pattern?
if utilities.is_set(PostScript) and mw.ustring.len(PostScript) > 1 then
utilities.set_message ('maint_postscript')
end
local Archived;
if utilities.is_set (ArchiveURL) then
if not utilities.is_set (ArchiveDate) then -- ArchiveURL set but ArchiveDate not set
utilities.set_message ('err_archive_missing_date'); -- emit an error message
ArchiveURL = ''; -- empty string for concatenation
ArchiveDate = ''; -- empty string for concatenation
end
else
if utilities.is_set (ArchiveDate) then -- ArchiveURL not set but ArchiveDate is set
utilities.set_message ('err_archive_date_missing_url'); -- emit an error message
ArchiveURL = ''; -- empty string for concatenation
ArchiveDate = ''; -- empty string for concatenation
end
end
if utilities.is_set (ArchiveURL) then
local arch_text;
local status, result = pcall(formatDate, ArchiveDate) -- РУВИКИ: человекочитаемые даты
if status then
ArchiveDate = string.format("<span class='date'>%s</span>", result)
else
ArchiveDate = string.format("<span class='error'>(Строка «%s» не является верной датой, пожалуйста, укажите дату в формате <code>ГГГГ-ММ-ДД</code>)</span>", ArchiveDate)
end
if "live" == UrlStatus or "" == UrlStatus then
arch_text = cfg.messages['archived'];
if sepc ~= "." then arch_text = arch_text:lower() end
if utilities.is_set (ArchiveDate) then
Archived = sepc .. ' ' .. utilities.substitute ( cfg.messages['archived-live'],
{external_link( ArchiveURL, arch_text, A:ORIGIN('ArchiveURL'), nil) .. ArchiveFormat, ArchiveDate } );
else
Archived = '';
end
if not utilities.is_set (OriginalURL) then
utilities.set_message ('err_archive_missing_url');
Archived = ''; -- empty string for concatenation
end
elseif utilities.is_set (OriginalURL) then -- UrlStatus is empty, 'dead', 'unfit', 'usurped', 'bot: unknown'
if utilities.in_array (UrlStatus, {'unfit', 'usurped', 'bot: unknown'}) then
arch_text = cfg.messages['archived-unfit'];
if sepc ~= "." then arch_text = arch_text:lower() end
Archived = sepc .. ' ' .. arch_text .. ArchiveDate; -- format already styled
if 'bot: unknown' == UrlStatus then
utilities.set_message ('maint_bot_unknown'); -- and add a category if not already added
else
utilities.set_message ('maint_unfit'); -- and add a category if not already added
end
else -- UrlStatus is empty, 'dead'
arch_text = cfg.messages['archived-dead'];
if sepc ~= "." then arch_text = arch_text:lower() end
if utilities.is_set (ArchiveDate) then
Archived = sepc .. " " .. utilities.substitute ( arch_text,
{ external_link( OriginalURL, cfg.messages['original'], OriginalURL_origin, OriginalAccess ) .. OriginalFormat, ArchiveDate } ); -- format already styled
else
Archived = ''; -- unset for concatenation
end
end
else -- OriginalUrl not set
utilities.set_message ('err_archive_missing_url');
Archived = ''; -- empty string for concatenation
end
elseif utilities.is_set (ArchiveFormat) then
Archived = ArchiveFormat; -- if set and ArchiveURL not set ArchiveFormat has error message
else
Archived = '';
end
local TranscriptURL = A['TranscriptURL']
local TranscriptFormat = A['TranscriptFormat'];
TranscriptFormat = style_format (TranscriptFormat, TranscriptURL, 'transcript-format', 'transcripturl');
local Transcript = A['Transcript'];
local TranscriptURL_origin = A:ORIGIN('TranscriptURL'); -- get name of parameter that holds TranscriptURL
if utilities.is_set (Transcript) then
if utilities.is_set (TranscriptURL) then
Transcript = external_link( TranscriptURL, Transcript, TranscriptURL_origin, nil );
end
Transcript = sepc .. ' ' .. Transcript .. TranscriptFormat;
elseif utilities.is_set (TranscriptURL) then
Transcript = external_link( TranscriptURL, nil, TranscriptURL_origin, nil );
end
local Publisher;
if utilities.is_set (PublicationDate) then
PublicationDate = wrap_msg ('published', PublicationDate);
end
if utilities.is_set (PublisherName) then
if utilities.is_set (PublicationPlace) then
Publisher = sepc .. " " .. PublicationPlace .. ": " .. PublisherName .. PublicationDate;
else
Publisher = sepc .. " " .. PublisherName .. PublicationDate;
end
elseif utilities.is_set (PublicationPlace) then
Publisher= sepc .. " " .. PublicationPlace .. PublicationDate;
else
Publisher = PublicationDate;
end
-- Several of the above rely upon detecting this as nil, so do it last.
if (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical) or utilities.is_set (TransPeriodical)) then
if utilities.is_set (Title) or utilities.is_set (TitleNote) then
Periodical = sepc .. " " .. format_periodical (ScriptPeriodical, ScriptPeriodical_origin, Periodical, TransPeriodical, TransPeriodical_origin);
else
Periodical = format_periodical (ScriptPeriodical, ScriptPeriodical_origin, Periodical, TransPeriodical, TransPeriodical_origin);
end
end
local Language = A['Language'];
if utilities.is_set (Language) then
Language = language_parameter (Language); -- format, categories, name from ISO639-1, etc.
else
Language=''; -- language not specified so make sure this is an empty string;
--[[ TODO: need to extract the wrap_msg from language_parameter
so that we can solve parentheses bunching problem with Format/Language/TitleType
]]
end
--[[
Handle the oddity that is cite speech. This code overrides whatever may be the value assigned to TitleNote (through |department=) and forces it to be " (Speech)" so that
the annotation directly follows the |title= parameter value in the citation rather than the |event= parameter value (if provided).
]]
if "speech" == config.CitationClass then -- cite speech only
TitleNote = TitleType; -- move TitleType to TitleNote so that it renders ahead of |event=
TitleType = ''; -- and unset
if utilities.is_set (Periodical) then -- if Periodical, perhaps because of an included |website= or |journal= parameter
if utilities.is_set (Conference) then -- and if |event= is set
Conference = Conference .. sepc .. " "; -- then add appropriate punctuation to the end of the Conference variable before rendering
end
end
end
-- Piece all bits together at last. Here, all should be non-nil.
-- We build things this way because it is more efficient in LUA
-- not to keep reassigning to the same string variable over and over.
local tcommon;
local tcommon2; -- used for book cite when |contributor= is set
if utilities.in_array (config.CitationClass, {"book", "citation"}) and not utilities.is_set (Periodical) then -- special cases for book cites
if utilities.is_set (Contributors) then -- when we are citing foreword, preface, introduction, etc.
tcommon = safe_join ({Title, TitleNote}, sepc); -- author and other stuff will come after this and before tcommon2
tcommon2 = safe_join ({TitleType, Series, Language, Volume, Others, Edition, Publisher}, sepc);
else
tcommon = safe_join ({Title, TitleNote, TitleType, Series, Language, Volume, Others, Edition, Publisher}, sepc);
end
elseif 'map' == config.CitationClass then -- special cases for cite map
if utilities.is_set (Chapter) then -- map in a book; TitleType is part of Chapter
tcommon = safe_join ({Title, Edition, Scale, Series, Language, Cartography, Others, Publisher, Volume}, sepc);
elseif utilities.is_set (Periodical) then -- map in a periodical
tcommon = safe_join ({Title, TitleType, Periodical, Scale, Series, Language, Cartography, Others, Publisher, Volume}, sepc);
else -- a sheet or stand-alone map
tcommon = safe_join ({Title, TitleType, Edition, Scale, Series, Language, Cartography, Others, Publisher}, sepc);
end
elseif 'episode' == config.CitationClass then -- special case for cite episode
tcommon = safe_join ({Title, TitleNote, TitleType, Series, Language, Edition, Publisher}, sepc);
else -- all other CS1 templates
tcommon = safe_join ({Title, TitleNote, Conference, Periodical, TitleType, Series, Language, Volume, Others, Edition, Publisher, Agency}, sepc);
end
if #ID_list > 0 then
ID_list = safe_join( { sepc .. " ", table.concat( ID_list, sepc .. " " ), ID }, sepc );
else
ID_list = ID;
end
local Via = A['Via'];
Via = utilities.is_set (Via) and wrap_msg ('via', Via) or '';
local idcommon;
if 'audio-visual' == config.CitationClass or 'episode' == config.CitationClass then -- special case for cite AV media & cite episode position transcript
idcommon = safe_join( { ID_list, URL, Archived, Transcript, AccessDate, Via, Quote }, sepc );
else
idcommon = safe_join( { ID_list, URL, Archived, AccessDate, Via, Quote }, sepc );
end
local text;
local pgtext = Position .. Sheet .. Sheets .. Page .. Pages .. At;
local OrigDate = A['OrigDate'];
OrigDate = utilities.is_set (OrigDate) and wrap_msg ('origdate', OrigDate) or '';
if utilities.is_set (Date) then
if utilities.is_set (Authors) or utilities.is_set (Editors) then -- date follows authors or editors when authors not set
Date = " (" .. Date .. ")" .. OrigDate .. sepc .. " "; -- in parentheses
else -- neither of authors and editors set
if (string.sub(tcommon, -1, -1) == sepc) then -- if the last character of tcommon is sepc
Date = " " .. Date .. OrigDate; -- Date does not begin with sepc
else
Date = sepc .. " " .. Date .. OrigDate; -- Date begins with sepc
end
end
end
if utilities.is_set (Authors) then
if (not utilities.is_set (Date)) then -- when date is set it's in parentheses; no Authors termination
Authors = terminate_name_list (Authors, sepc); -- when no date, terminate with 0 or 1 sepc and a space
end
if utilities.is_set (Editors) then
local in_text = '';
local post_text = '';
if utilities.is_set (Chapter) and 0 == #c then
in_text = cfg.messages['in'] .. ' ';
if (sepc ~= '.') then
in_text = in_text:lower(); -- lowercase for cs2
end
end
if EditorCount <= 1 then
post_text = ' (' .. cfg.messages['editor'] .. ')'; -- be consistent with no-author, no-date case
else
post_text = ' (' .. cfg.messages['editors'] .. ')';
end
Editors = terminate_name_list (in_text .. Editors .. post_text, sepc); -- terminate with 0 or 1 sepc and a space
end
if utilities.is_set (Contributors) then -- book cite and we're citing the intro, preface, etc.
local by_text = sepc .. ' ' .. cfg.messages['by'] .. ' ';
if (sepc ~= '.') then by_text = by_text:lower() end -- lowercase for cs2
Authors = by_text .. Authors; -- author follows title so tweak it here
if utilities.is_set (Editors) and utilities.is_set (Date) then -- when Editors make sure that Authors gets terminated
Authors = terminate_name_list (Authors, sepc); -- terminate with 0 or 1 sepc and a space
end
if (not utilities.is_set (Date)) then -- when date is set it's in parentheses; no Contributors termination
Contributors = terminate_name_list (Contributors, sepc); -- terminate with 0 or 1 sepc and a space
end
text = safe_join( {Contributors, Date, Chapter, tcommon, Authors, Place, Editors, tcommon2, pgtext, idcommon }, sepc );
else
text = safe_join( {Authors, Date, Chapter, Place, Editors, tcommon, pgtext, idcommon }, sepc );
end
elseif utilities.is_set (Editors) then
if utilities.is_set (Date) then
if EditorCount <= 1 then
Editors = Editors .. cfg.presentation['sep_name'] .. cfg.messages['editor'];
else
Editors = Editors .. cfg.presentation['sep_name'] .. cfg.messages['editors'];
end
else
if EditorCount <= 1 then
Editors = Editors .. " (" .. cfg.messages['editor'] .. ")" .. sepc .. " "
else
Editors = Editors .. " (" .. cfg.messages['editors'] .. ")" .. sepc .. " "
end
end
text = safe_join( {Editors, Date, Chapter, Place, tcommon, pgtext, idcommon}, sepc );
else
if utilities.in_array (config.CitationClass, {"journal", "citation"}) and utilities.is_set (Periodical) then
text = safe_join( {Chapter, Place, tcommon, pgtext, Date, idcommon}, sepc );
else
text = safe_join( {Chapter, Place, tcommon, Date, pgtext, idcommon}, sepc );
end
end
if utilities.is_set (PostScript) and PostScript ~= sepc then
text = safe_join( {text, sepc}, sepc ); -- Deals with italics, spaces, etc.
if '.' == sepc then -- remove final seperator if present
text = text:gsub ('%' .. sepc .. '$', ''); -- dot must be escaped here
else
text = mw.ustring.gsub (text, sepc .. '$', ''); -- using ustring for non-dot sepc (likely a non-Latin character)
end
end
text = safe_join( {text, PostScript}, sepc );
-- Now enclose the whole thing in a <cite> element
local options_t = {};
options_t.class = cite_class_attribute_make (config.CitationClass, Mode);
local Ref = is_valid_parameter_value (A['Ref'], A:ORIGIN('Ref'), cfg.keywords_lists['ref'], nil, true); -- nil when |ref=harv; A['Ref'] else
-- Если указан параметр ref, то формируем ref-якорь по логике из рувики
-- Если параметр не указан или ref=harv, то формируем якорь по енвики
-- После зачистки всех ref=harv (~350), можно будет убрать код внутри utilities.is_set(Ref)
if 'none' ~= cfg.keywords_xlate[(Ref and Ref:lower()) or ''] then
local citeref_id = Ref
local year = first_set ({Year, anchor_year}, 2); -- Year first for legacy citations and for YMD dates that require disambiguation
if not utilities.is_set(Ref) then
local namelist_t = {}; -- holds selected contributor, author, editor name list
if #c > 0 then -- if there is a contributor list
namelist_t = c; -- select it
elseif #a > 0 then -- or an author list
namelist_t = a;
elseif #e > 0 then -- or an editor list
namelist_t = e;
end
if #namelist_t > 0 then -- if there are names in namelist_t
citeref_id = make_citeref_id (namelist_t, year); -- go make the CITEREF anchor
if mw.uri.anchorEncode (citeref_id) == ((Ref and mw.uri.anchorEncode (Ref)) or '') then -- Ref may already be encoded (by {{sfnref}}) so citeref_id must be encoded before comparison
utilities.set_message ('maint_ref_duplicates_default');
end
else
citeref_id = ''; -- unset
end
elseif mw.ustring.sub(Ref, 0, 7) ~= 'CITEREF' then -- для рувики: иная генерация ref-якорей
if mw.ustring.match(citeref_id, '%d%d%d%d') then
citeref_id = 'CITEREF' .. citeref_id
else
local yearForRef = nil
if year and mw.ustring.match(year, '^%d%d%d%d$') then
yearForRef = mw.ustring.match(year, '^%d%d%d%d$')
elseif Date and mw.ustring.match(Date, '%d%d%d%d') then
yearForRef = mw.ustring.match(Date, '%d%d%d%d')
end
if yearForRef then
citeref_id = 'CITEREF' .. citeref_id .. yearForRef
else
citeref_id = '' -- TODO: для рувики: выдавать ошибку?
end
end
end
options_t.id = citeref_id or '';
end
if string.len (text:gsub('%b<>', '')) <= 2 then -- remove html and html-like tags; then get length of what remains;
z.error_cats_t = {}; -- blank the categories list
z.error_msgs_t = {}; -- blank the error messages list
OCinSoutput = nil; -- blank the metadata string
text = ''; -- blank the the citation
utilities.set_message ('err_empty_citation'); -- set empty citation message and category
end
local render_t = {}; -- here we collect the final bits for concatenation into the rendered citation
if utilities.is_set (options_t.id) then -- here we wrap the rendered citation in <cite ...>...</cite> tags
table.insert (render_t, utilities.substitute (cfg.presentation['cite-id'], {mw.uri.anchorEncode(options_t.id), mw.text.nowiki(options_t.class), text})); -- when |ref= is set or when there is a namelist
else
table.insert (render_t, utilities.substitute (cfg.presentation['cite'], {mw.text.nowiki(options_t.class), text})); -- when |ref=none or when namelist_t empty and |ref= is missing or is empty
end
if OCinSoutput then -- blanked when citation is 'empty' so don't bother to add boilerplate metadata span
table.insert (render_t, utilities.substitute (cfg.presentation['ocins'], OCinSoutput)); -- format and append metadata to the citation
end
local template_name = ('citation' == config.CitationClass) and 'citation' or 'cite ' .. (cfg.citation_class_map_t[config.CitationClass] or config.CitationClass);
local template_link = '[[Template:' .. template_name .. '|' .. template_name .. ']]';
local msg_prefix = '<code class="cs1-code">{{' .. template_link .. '}}</code>: ';
if 0 ~= #z.error_msgs_t then
mw.addWarning (utilities.substitute (cfg.messages.warning_msg_e, template_link));
table.insert (render_t, ' '); -- insert a space between citation and its error messages
table.sort (z.error_msgs_t); -- sort the error messages list; sorting includes wrapping <span> and <code> tags; hidden-error sorts ahead of visible-error
local hidden = true; -- presume that the only error messages emited by this template are hidden
for _, v in ipairs (z.error_msgs_t) do -- spin through the list of error messages
if v:find ('cs1-visible-error', 1, true) then -- look for the visible error class name
hidden = false; -- found one; so don't hide the error message prefix
break; -- and done because no need to look further
end
end
z.error_msgs_t[1] = table.concat ({utilities.error_comment (msg_prefix, hidden), z.error_msgs_t[1]}); -- add error message prefix to first error message to prevent extraneous punctuation
table.insert (render_t, table.concat (z.error_msgs_t, '; ')); -- make a big string of error messages and add it to the rendering
end
if 0 ~= #z.maint_cats_t then
mw.addWarning (utilities.substitute (cfg.messages.warning_msg_m, template_link));
table.sort (z.maint_cats_t); -- sort the maintenance messages list
local maint_msgs_t = {}; -- here we collect all of the maint messages
if 0 == #z.error_msgs_t then -- if no error messages
table.insert (maint_msgs_t, msg_prefix); -- insert message prefix in maint message livery
end
for _, v in ipairs( z.maint_cats_t ) do -- append maintenance categories
table.insert (maint_msgs_t, -- assemble new maint message and add it to the maint_msgs_t table
table.concat ({v, ' (', utilities.substitute (cfg.messages[':cat wikilink'], v), ')'})
);
end
table.insert (render_t, utilities.substitute (cfg.presentation['hidden-maint'], table.concat (maint_msgs_t, ' '))); -- wrap the group of maint messages with proper presentation and save
end
if not no_tracking_cats then
local sort_key;
local cat_wikilink = 'cat wikilink';
if cfg.enable_sort_keys then -- when namespace sort keys enabled
local namespace_number = mw.title.getCurrentTitle().namespace; -- get namespace number for this wikitext
sort_key = (0 ~= namespace_number and (cfg.name_space_sort_keys[namespace_number] or cfg.name_space_sort_keys.other)) or nil; -- get sort key character; nil for mainspace
cat_wikilink = (not sort_key and 'cat wikilink') or 'cat wikilink sk'; -- make <cfg.messages> key
end
for _, v in ipairs (z.error_cats_t) do -- append error categories
table.insert (render_t, utilities.substitute (cfg.messages[cat_wikilink], {v, sort_key}));
end
for _, v in ipairs (z.maint_cats_t) do -- append maintenance categories
table.insert (render_t, utilities.substitute (cfg.messages[cat_wikilink], {v, sort_key}));
end
-- for _, v in ipairs (z.prop_cats_t) do -- append properties categories
-- table.insert (render_t, utilities.substitute (cfg.messages['cat wikilink'], v)); -- no sort keys
-- end
end
return table.concat (render_t); -- make a big string and done
end
--[[--------------------------< V A L I D A T E >--------------------------------------------------------------
Looks for a parameter's name in one of several whitelists.
Parameters in the whitelist can have three values:
true - active, supported parameters
false - deprecated, supported parameters
nil - unsupported parameters
]]
local function validate (name, cite_class, empty)
local name = tostring (name);
local enum_name; -- parameter name with enumerator (if any) replaced with '#'
local state;
local function state_test (state, name) -- local function to do testing of state values
if true == state then return true; end -- valid actively supported parameter
if false == state then
if empty then return nil; end -- empty deprecated parameters are treated as unknowns
deprecated_parameter (name); -- parameter is deprecated but still supported
return true;
end
if 'tracked' == state then
local base_name = name:gsub ('%d', ''); -- strip enumerators from parameter names that have them to get the base name
utilities.add_prop_cat ('tracked-param', {base_name}, base_name); -- add a properties category; <base_name> modifies <key>
return true;
end
return nil;
end
if name:find ('#') then -- # is a cs1|2 reserved character so parameters with # not permitted
return nil;
end
-- replace enumerator digit(s) with # (|last25= becomes |last#=) (mw.ustring because non-Western 'local' digits)
enum_name = mw.ustring.gsub (name, '%d+$', '#'); -- where enumerator is last charaters in parameter name (these to protect |s2cid=)
enum_name = mw.ustring.gsub (enum_name, '%d+([%-l])', '#%1'); -- where enumerator is in the middle of the parameter name; |author#link= is the oddity
if 'document' == cite_class then -- special case for {{cite document}}
state = whitelist.document_parameters_t[enum_name]; -- this list holds enumerated and nonenumerated parameters
if true == state_test (state, name) then return true; end
return false;
end
if utilities.in_array (cite_class, whitelist.preprint_template_list_t) then -- limited parameter sets allowed for these templates
state = whitelist.limited_parameters_t[enum_name]; -- this list holds enumerated and nonenumerated parameters
if true == state_test (state, name) then return true; end
state = whitelist.preprint_arguments_t[cite_class][name]; -- look in the parameter-list for the template identified by cite_class
if true == state_test (state, name) then return true; end
return false; -- not supported because not found or name is set to nil
end -- end limited parameter-set templates
if utilities.in_array (cite_class, whitelist.unique_param_template_list_t) then -- template-specific parameters for templates that accept parameters from the basic argument list
state = whitelist.unique_arguments_t[cite_class][name]; -- look in the template-specific parameter-lists for the template identified by cite_class
if true == state_test (state, name) then return true; end
end -- if here, fall into general validation
state = whitelist.common_parameters_t[enum_name]; -- all other templates; all normal parameters allowed; this list holds enumerated and nonenumerated parameters
if true == state_test (state, name) then return true; end
return false; -- not supported because not found or name is set to nil
end
--[=[-------------------------< I N T E R _ W I K I _ C H E C K >----------------------------------------------
check <value> for inter-language interwiki-link markup. <prefix> must be a MediaWiki-recognized language
code. when these values have the form (without leading colon):
[[<prefix>:link|label]] return label as plain-text
[[<prefix>:link]] return <prefix>:link as plain-text
return value as is else
]=]
local function inter_wiki_check (parameter, value)
local prefix = value:match ('%[%[(%a+):'); -- get an interwiki prefix if one exists
local _;
if prefix and cfg.inter_wiki_map[prefix:lower()] then -- if prefix is in the map, needs preceding colon so
utilities.set_message ('err_bad_paramlink', parameter); -- emit an error message
_, value, _ = utilities.is_wikilink (value); -- extract label portion from wikilink
end
return value;
end
--[[--------------------------< M I S S I N G _ P I P E _ C H E C K >------------------------------------------
Look at the contents of a parameter. If the content has a string of characters and digits followed by an equal
sign, compare the alphanumeric string to the list of cs1|2 parameters. If found, then the string is possibly a
parameter that is missing its pipe. There are two tests made:
{{cite ... |title=Title access-date=2016-03-17}} -- the first parameter has a value and whitespace separates that value from the missing pipe parameter name
{{cite ... |title=access-date=2016-03-17}} -- the first parameter has no value (whitespace after the first = is trimmed by MediaWiki)
cs1|2 shares some parameter names with XML/HTML attributes: class=, title=, etc. To prevent false positives XML/HTML
tags are removed before the search.
If a missing pipe is detected, this function adds the missing pipe maintenance category.
]]
local function missing_pipe_check (parameter, value)
local capture;
value = value:gsub ('%b<>', ''); -- remove XML/HTML tags because attributes: class=, title=, etc.
capture = value:match ('%s+(%a[%w%-]+)%s*=') or value:match ('^(%a[%w%-]+)%s*='); -- find and categorize parameters with possible missing pipes
if capture and validate (capture) then -- if the capture is a valid parameter name
utilities.set_message ('err_missing_pipe', parameter);
end
end
--[[--------------------------< H A S _ E X T R A N E O U S _ P U N C T >--------------------------------------
look for extraneous terminal punctuation in most parameter values; parameters listed in skip table are not checked
]]
local function has_extraneous_punc (param, value)
if 'number' == type (param) then
return;
end
param = param:gsub ('%d+', '#'); -- enumerated name-list mask params allow terminal punct; normalize
if cfg.punct_skip[param] then
return; -- parameter name found in the skip table so done
end
if value:match ('[,;:]$') then
utilities.set_message ('maint_extra_punct'); -- has extraneous punctuation; add maint cat
end
if value:match ('^=') then -- sometimes an extraneous '=' character appears ...
utilities.set_message ('maint_extra_punct'); -- has extraneous punctuation; add maint cat
end
end
--[[--------------------------< H A S _ E X T R A N E O U S _ U R L >------------------------------------------
look for extraneous url parameter values; parameters listed in skip table are not checked
]]
local function has_extraneous_url (url_param_t)
local url_error_t = {};
check_for_url (url_param_t, url_error_t); -- extraneous url check
if 0 ~= #url_error_t then -- non-zero when there are errors
table.sort (url_error_t);
utilities.set_message ('err_param_has_ext_link', {utilities.make_sep_list (#url_error_t, url_error_t)}); -- add this error message
end
end
--[[--------------------------< C I T A T I O N >--------------------------------------------------------------
This is used by templates such as {{cite book}} to create the actual citation text.
]]
local function citation(frame)
Frame = frame; -- save a copy in case we need to display an error message in preview mode
local config = {}; -- table to store parameters from the module {{#invoke:}}
for k, v in pairs( frame.args ) do -- get parameters from the {{#invoke}} frame
config[k] = v;
-- args[k] = v; -- crude debug support that allows us to render a citation from module {{#invoke:}}; skips parameter validation; TODO: keep?
end
-- i18n: set the name that your wiki uses to identify sandbox subpages from sandbox template invoke (or can be set here)
local sandbox = ((config.SandboxPath and '' ~= config.SandboxPath) and config.SandboxPath) or '/sandbox'; -- sandbox path from {{#invoke:Citation/CS1/sandbox|citation|SandboxPath=/...}}
is_sandbox = nil ~= string.find (frame:getTitle(), sandbox, 1, true); -- is this invoke the sandbox module?
sandbox = is_sandbox and sandbox or ''; -- use i18n sandbox to load sandbox modules when this module is the sandox; live modules else
local pframe = frame:getParent()
local styles;
cfg = mw.loadData ('Module:Citation/CS1/Configuration' .. sandbox); -- load sandbox versions of support modules when {{#invoke:Citation/CS1/sandbox|...}}; live modules else
whitelist = mw.loadData ('Module:Citation/CS1/Whitelist' .. sandbox);
utilities = require ('Module:Citation/CS1/Utilities' .. sandbox);
validation = require ('Module:Citation/CS1/Date_validation' .. sandbox);
identifiers = require ('Module:Citation/CS1/Identifiers' .. sandbox);
metadata = require ('Module:Citation/CS1/COinS' .. sandbox);
styles = 'Module:Citation/CS1' .. sandbox .. '/styles.css';
utilities.set_selected_modules (cfg); -- so that functions in Utilities can see the selected cfg tables
identifiers.set_selected_modules (cfg, utilities); -- so that functions in Identifiers can see the selected cfg tables and selected Utilities module
validation.set_selected_modules (cfg, utilities); -- so that functions in Date validataion can see selected cfg tables and the selected Utilities module
metadata.set_selected_modules (cfg, utilities); -- so that functions in COinS can see the selected cfg tables and selected Utilities module
z = utilities.z; -- table of error and category tables in Module:Citation/CS1/Utilities
is_preview_mode = not utilities.is_set (frame:preprocess ('{{REVISIONID}}'));
local args = {}; -- table where we store all of the template's arguments
local suggestions = {}; -- table where we store suggestions if we need to loadData them
local error_text; -- used as a flag
local capture; -- the single supported capture when matching unknown parameters using patterns
local empty_unknowns = {}; -- sequence table to hold empty unknown params for error message listing
for k, v in pairs( pframe.args ) do -- get parameters from the parent (template) frame
v = mw.ustring.gsub (v, '^%s*(.-)%s*$', '%1'); -- trim leading/trailing whitespace; when v is only whitespace, becomes empty string
if v ~= '' then
if ('string' == type (k)) then
k = mw.ustring.gsub (k, '%d', cfg.date_names.local_digits); -- for enumerated parameters, translate 'local' digits to Western 0-9
end
if not validate( k, config.CitationClass ) then
if type (k) ~= 'string' then -- exclude empty numbered parameters
if v:match("%S+") ~= nil then
error_text = utilities.set_message ('err_text_ignored', {v});
end
elseif validate (k:lower(), config.CitationClass) then
error_text = utilities.set_message ('err_parameter_ignored_suggest', {k, k:lower()}); -- suggest the lowercase version of the parameter
else
if nil == suggestions.suggestions then -- if this table is nil then we need to load it
suggestions = mw.loadData ('Module:Citation/CS1/Suggestions' .. sandbox); --load sandbox version of suggestion module when {{#invoke:Citation/CS1/sandbox|...}}; live module else
end
for pattern, param in pairs (suggestions.patterns) do -- loop through the patterns to see if we can suggest a proper parameter
capture = k:match (pattern); -- the whole match if no capture in pattern else the capture if a match
if capture then -- if the pattern matches
param = utilities.substitute (param, capture); -- add the capture to the suggested parameter (typically the enumerator)
if validate (param, config.CitationClass) then -- validate the suggestion to make sure that the suggestion is supported by this template (necessary for limited parameter lists)
error_text = utilities.set_message ('err_parameter_ignored_suggest', {k, param}); -- set the suggestion error message
else
error_text = utilities.set_message ('err_parameter_ignored', {k}); -- suggested param not supported by this template
v = ''; -- unset
end
end
end
if not utilities.is_set (error_text) then -- couldn't match with a pattern, is there an explicit suggestion?
if (suggestions.suggestions[ k:lower() ] ~= nil) and validate (suggestions.suggestions[ k:lower() ], config.CitationClass) then
utilities.set_message ('err_parameter_ignored_suggest', {k, suggestions.suggestions[ k:lower() ]});
else
utilities.set_message ('err_parameter_ignored', {k});
v = ''; -- unset value assigned to unrecognized parameters (this for the limited parameter lists)
end
end
end
end
args[k] = v; -- save this parameter and its value
elseif not utilities.is_set (v) then -- for empty parameters
if not validate (k, config.CitationClass, true) then -- is this empty parameter a valid parameter
k = ('' == k) and '(empty string)' or k; -- when k is empty string (or was space(s) trimmed to empty string), replace with descriptive text
table.insert (empty_unknowns, utilities.wrap_style ('parameter', k)); -- format for error message and add to the list
end
-- crude debug support that allows us to render a citation from module {{#invoke:}} TODO: keep?
-- elseif args[k] ~= nil or (k == 'postscript') then -- when args[k] has a value from {{#invoke}} frame (we don't normally do that)
-- args[k] = v; -- overwrite args[k] with empty string from pframe.args[k] (template frame); v is empty string here
end -- not sure about the postscript bit; that gets handled in parameter validation; historical artifact?
end
if 0 ~= #empty_unknowns then -- create empty unknown error message
utilities.set_message ('err_param_unknown_empty', {
1 == #empty_unknowns and '' or 's',
utilities.make_sep_list (#empty_unknowns, empty_unknowns)
});
end
local url_param_t = {};
for k, v in pairs( args ) do
if 'string' == type (k) then -- don't evaluate positional parameters
has_invisible_chars (k, v); -- look for invisible characters
end
has_extraneous_punc (k, v); -- look for extraneous terminal punctuation in parameter values
missing_pipe_check (k, v); -- do we think that there is a parameter that is missing a pipe?
args[k] = inter_wiki_check (k, v); -- when language interwiki-linked parameter missing leading colon replace with wiki-link label
if 'string' == type (k) and not cfg.url_skip[k] then -- when parameter k is not positional and not in url skip table
url_param_t[k] = v; -- make a parameter/value list for extraneous url check
end
end
has_extraneous_url (url_param_t); -- look for url in parameter values where a url does not belong
return table.concat ({
frame:extensionTag ('templatestyles', '', {src=styles}),
citation0( config, args)
});
end
--[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------
]]
return {citation = citation};
79118ee25d3a893b095e8a280156cc50dc140901
Модуль:Demo
828
183
408
2024-05-02T11:40:03Z
ruwiki>Vavilexxx
0
исправление
Scribunto
text/plain
local p = {}
local getArgs = require('Модуль:Arguments').getArgs
local function hasValue(param)
if param and param:find('%S') then
return true
end
end
--creates a frame object that cannot access any of the parent's args
--unless a table containing a list keys of not to inherit is provided
function disinherit(frame, onlyTheseKeys)
local parent = frame:getParent() or frame
local orphan = parent:newChild{}
orphan.getParent = parent.getParent --returns nil
orphan.args = {}
if onlyTheseKeys then
local family = {parent, frame}
for f = 1, 2 do
for k, v in pairs(family[f] and family[f].args or {}) do
orphan.args[k] = orphan.args[k] or v
end
end
parent.args = mw.clone(orphan.args)
setmetatable(orphan.args, nil)
for _, k in ipairs(onlyTheseKeys) do
rawset(orphan.args, k, nil)
end
end
return orphan, parent
end
function p.get(frame, arg, passArgs)
local orphan, frame = disinherit(frame, passArgs and {arg or 1})
local code, noWiki, preserve = frame.args[arg or 1] or ''
local kill_categories = not frame.args.save_categories
local tag, sep
if code:match'nowiki' then
local placeholder, preserve = ('6'):char(), {}
-- We replace "}%-" and "%-{" because of some server bug probably connected to
-- [[mw:Parsoid/MediaWiki DOM spec/Language conversion blocks]] and leading to
-- =mw.text.unstripNoWiki(mw.getCurrentFrame():preprocess('<nowiki>}-</nowiki>'))
-- outputting '}-' instead of "}-", while it's ok with "<nowiki>} -</nowiki>"
code = mw.text.unstripNoWiki(code)
:gsub('<', '<')
:gsub('>', '>')
:gsub('}%-', '}-')
:gsub('%-{', '-{')
if (mw.text.trim(code):match'\n') then
tag = 'pre'
sep = ''
end
noWiki = code:gsub('%%', placeholder)
for k in noWiki:gmatch('&.-;') do
table.insert(preserve, (k:gsub('&', '&')))
noWiki = noWiki:gsub('(&.-;)', '%%%s')
end
noWiki = mw.text.nowiki(noWiki):format(unpack(preserve)):gsub(placeholder, '%%')
end
return {
source = noWiki or code,
output = orphan:preprocess(code)
:gsub(kill_categories and '%[%[Категория:.-%]%]' or '', '')
:gsub(kill_categories and '%[%[К:.-%]%]' or '', '')
:gsub(kill_categories and '%[%[Category:.-%]%]' or '', ''),
frame = frame,
args = getArgs(frame),
tag = tag,
sep = sep
}
end
function p.main(frame, demoTable)
local show = demoTable or p.get(frame)
local args = show.args
local yesno = require('Module:Yesno')
args.reverse = yesno(args.reverse, false)
args.tag = hasValue(args.tag) and args.tag or hasValue(show.tag) and show.tag or "code"
args.sep = args.sep or args.br or show.sep
args.sep = tonumber(args.sep) and ('<br>'):rep(args.sep or 0) or args.sep or (args.tag == 'pre' and '' or ' → ')
if show[args.result_arg] then
return show[args.result_arg]
end
return args.reverse
and string.format(
'%s%s<%s%s%s>%s</%s>',
show.output,
args.sep,
args.tag,
hasValue(args.class) and string.format(' class="%s"', args.class) or '',
hasValue(args.style) and string.format(' style="%s"', args.style) or '',
show.source,
args.tag
)
or string.format(
'<%s%s%s>%s</%s>%s%s',
args.tag,
hasValue(args.class) and string.format(' class="%s"', args.class) or '',
hasValue(args.style) and string.format(' style="%s"', args.style) or '',
show.source,
args.tag,
args.sep,
show.output
)
end
--passing of args into other module without preprocessing
function p.module(frame)
local orphan, frame = disinherit(frame, {
'demo_template',
'demo_module',
'demo_module_func',
'demo_main',
'demo_br',
'demo_result_arg',
'demo_save_categories'
})
local template = frame.args.demo_template and 'Template:'..frame.args.demo_template
local demoFunc = frame.args.demo_module_func or 'main\n'
local demoModule = require('Module:' .. frame.args.demo_module)[demoFunc:match('^%s*(.-)%s*$')]
frame.args.br, frame.args.result_arg = frame.args.demo_br or frame.args.demo_sep, frame.args.demo_result_arg
local kill_categories = not save_categories
if demoModule then
local named = {insert = function(self, ...) table.insert(self, ...) return self end}
local source = {insert = named.insert, '{{', frame.args.demo_template or frame.args.demo_module, '\n'}
if not template then
source:insert(2, '#invoke:'):insert(4, '|'):insert(5, demoFunc)
end
local insertNamed = #source + 1
for k, v in pairs(orphan.args) do
local nan, insert = type(k) ~= 'number', {v}
local target = nan and named or source
target:insert'|'
if nan then
target:insert(k):insert'=':insert'\n'
table.insert(insert, 1, #target)
end
target:insert(unpack(insert))
local nowiki = v:match('nowiki')
if nowiki or v:match('{{.-}}') then
orphan.args[k] = frame:preprocess(nowiki and mw.text.unstripNoWiki(v) or v)
end
end
source:insert'}}'
table.insert(source, insertNamed, table.concat(named))
return p.main(orphan, {
source = mw.text.encode(table.concat(source), "<>'|=~"),
output = tostring(demoModule(orphan)):gsub(kill_categories and '%[%[Категория:.-%]%]' or '', ''):gsub(kill_categories and '%[%[К:.-%]%]' or '', ''):gsub(kill_categories and '%[%[Category:.-%]%]' or '', ''),
frame = frame
})
else
return "ERROR: Invalid module function: "..demoFunc
end
end
return p
9beaf8f8041a39ae73ba17b2f70609171c4196d3
Шаблон:Действия для страницы/styles.css
10
175
392
2024-05-02T17:22:30Z
ruwiki>Stjn
0
fix
sanitized-css
text/css
.ts-tlinks-tlinks {
font-weight: normal;
float: right;
line-height: inherit;
}
.ts-tlinks-tlinks .mw-editsection-divider {
display: inline;
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
a003e896d263c29e66d2246b210e5d73e577ea46
Шаблон:Действия для страницы
10
174
390
2024-05-02T17:24:27Z
ruwiki>Stjn
0
никаких пиксельных fontsize
wikitext
text/x-wiki
<templatestyles src="Шаблон:Действия для страницы/styles.css" /><div style="{{#ifeq: {{yesno-yes|{{{right|}}}}} | yes || float:none; }}" class="ts-tlinks-tlinks mw-editsection-like plainlinks"><span class="mw-editsection-bracket">[</span><!--
-->{{join|separator=<span class="mw-editsection-divider"> &#124; </span>
|1={{#ifexist: {{#rel2abs: {{{lc|}}} }}
| {{#ifeq: {{{dislooklink|{{{noview|}}}}}} | yes || [[{{{lc}}}|просмотр]] }}
}}
|2={{#ifexist: {{#rel2abs: {{{lc|}}} }}
| [[Special:EditPage/{{#rel2abs: {{{lc}}} }}|править]]
}}
|3={{#ifexist: {{#rel2abs: {{{lc|}}} }}
| {{#ifeq: {{{dishistlink|{{{nohistory|}}}}}} | yes || [[Special:PageHistory/{{#rel2abs: {{{lc}}} }}|история]] }}
}}
|4={{#ifexist: {{#rel2abs: {{{lc|}}} }}
|
| [{{fullurl:{{#rel2abs: {{{lc}}} }}|action=edit&redlink=1}} создать]
}}
|5={{#ifeq: {{{diswatchlink|{{{nowatch|}}}}}} | yes || [{{fullurl:{{#rel2abs: {{{lc}}} }}|action=watch}} следить] }}
|6={{#ifeq: {{{disupdlink|{{{noupdate|}}}}}} | yes || {{очистить кэш|обновить|nocat=1}}</span> }}
}}<span class="mw-editsection-bracket">]</span></div><noinclude>
{{doc}}
</noinclude>
9ee2c9eed92e2ecc9377a7b9486ad8bc214a83d4
Модуль:Wikidata/Medals
828
284
729
2024-05-04T17:24:40Z
ruwiki>Putnik
0
импорт списка дубликатов из [[az:Modul:Wikidata/Medals]]
Scribunto
text/plain
local WDS = require( 'Module:WikidataSelectors' )
local moduleDate = require( 'Module:Wikidata/date' )
local awardsOrder = mw.ext.data.get( "Wikidata/awards order.tab" )
local p = {}
local config = {
--Hide award with key QID if there is a reward with value QID
absorption = {
Q16675272 = 'Q654471',
Q16481808 = 'Q8706404',
Q1948730 = 'Q178473',
Q1980962 = 'Q208167',
Q2032399 = 'Q2046996',
Q102183407 = 'Q103819965',
Q1262166 = 'Q80589',
Q749849 = 'Q1358055',
Q4287121 = 'Q4137462',
}
}
--Get string with dates from qualifiers table
local function datesFromQualifier( context, options, qualifierId )
local dates = {}
local qualifiers = options.qualifiers[ qualifierId ]
if qualifiers then
for _, qualifier in pairs( qualifiers ) do
if qualifier.datavalue then
local dateValue = moduleDate.formatDate( context, options, qualifier.datavalue.value )
if dateValue then
table.insert( dates, dateValue )
end
end
end
end
return table.concat( dates, ', ' )
end
--Property function for [[d:Property:P166]]
function p.formatProperty( context, options )
if ( not context ) then error( 'context not specified' ); end;
if ( not options ) then error( 'options not specified' ); end;
if ( not options.entityId ) then error( 'options.entityId missing' ); end;
local claims;
if options.property then -- TODO: Почему тут может не быть property?
claims = context.selectClaims( options, options.property );
end
if claims == nil then
return '' --TODO error?
end
-- Обход всех заявлений утверждения и с накоплением оформленых
-- предпочтительных заявлений в таблице.
local formattedData = {}
for i, claim in ipairs( claims ) do
if ( claim.mainsnak and
claim.mainsnak and
claim.mainsnak.datavalue and
claim.mainsnak.datavalue.type == 'wikibase-entityid'
) then
local valueId = claim.mainsnak.datavalue.value.id
local formattedStatement = context.formatStatement( options, claim )
-- здесь может вернуться либо оформленный текст заявления, либо строка ошибки, либо nil
if ( formattedStatement and formattedStatement ~= '' ) then
formattedStatement = '<span class="wikidata-claim" data-wikidata-property-id="' .. string.upper( options.property ) .. '" data-wikidata-claim-id="' .. claim.id .. '">' .. formattedStatement .. '</span>'
table.insert( formattedData, {
id = valueId,
html = formattedStatement,
} )
end
end
end
-- Удаление дублей (медаль + звание -> звание)
for i, awardData in ipairs( formattedData ) do
local isAbsorptionFound = false
if config.absorption[ awardData.id ] then
local absorptionAwardId = config.absorption[ awardData.id ]
for _, absorptionAwardData in ipairs( formattedData ) do
if absorptionAwardData.id == absorptionAwardId then
isAbsorptionFound = true
break
end
end
end
if isAbsorptionFound then
table.remove( formattedData, i )
end
end
-- Сортировка медалей по старшинству
local orderedData = {}
local lastValue;
if ( type (awardsOrder) == 'table' ) then
-- Если не отсохла stuctured data
for i, awardFields in ipairs( awardsOrder.data ) do
local awardOrder = awardFields[ 1 ]
if awardOrder == '-' then
-- separator
if lastValue ~= '-' then
table.insert( orderedData, '<br>' )
lastHeight = nil
end
else
for k, awardData in ipairs( formattedData ) do
if awardOrder == awardData.id and not awardData.used then
table.insert( orderedData, awardData.html )
formattedData[ k ].used = true
end
end
end
end
end
for i, awardData in ipairs( formattedData ) do
if not awardData.used then
table.insert( orderedData, awardData.html )
end
end
local lastHeight
for i, awardHtml in ipairs( orderedData ) do
local height = mw.ustring.match( awardHtml, 'x%d+px' )
if height and lastHeight and height ~= lastHeight then
table.insert( orderedData, i, '<br>' )
end
lastHeight = height
end
-- создание текстовой строки со списком оформленых заявлений из таблицы
local out = mw.text.listToText( orderedData, options.separator, options.conjunction )
if out ~= '' then
if options.before then
out = options.before .. out
end
if options.after then
out = out .. options.after
end
end
return out
end
local function getImageFromProperty( entityId, propertyId )
local imageClaims = WDS.load( entityId, propertyId )
if imageClaims and #imageClaims > 0 then
for _, claim in ipairs( imageClaims ) do
if claim.type == 'statement' and claim.mainsnak.snaktype == 'value' then
return claim.mainsnak.datavalue.value
end
end
end
return nil
end
-- Получение изображения (планки или иконки) и его размера
function p.getImageFromEntity( entityId, actualDate )
if type( entityId ) ~= "string" then
entityId = entityId.id
end
local image = nil
local size = 'x17px'
local border = false
-- получение изображения планки из элемента
image = getImageFromProperty( entityId, 'P2425' )
if image then
border = true
end
-- получение иконки из элемента
if not image then
image = getImageFromProperty( entityId, 'P2910' )
if image then
size = '40x40px'
end
end
return image, size, border
end
--Value function for [[d:Property:P166]]
function p.formatValue( context, options, statement )
local entityId = statement.id
if not entityId then
return statement
end
local label = mw.wikibase.getLabel( entityId )
local image, size, border = p.getImageFromEntity( entityId )
local recipientCategory = ''
if not options.nocat and options.nocat ~= '' then
recipientCategory = context.extractCategory( { category = 'P7084[P4224:Q24571879]' }, entityId )
if recipientCategory == '' then
recipientCategory = context.extractCategory( { category = 'P2517' }, entityId )
end
end
local dates = ''
if options.qualifiers then
local startDates = {}
dates = datesFromQualifier( context, options, 'P580' )
if dates ~= '' then
local endDates = datesFromQualifier( context, options, 'P582' )
if endDates and endDates ~= '' then
dates = dates .. ' — ' .. endDates
end
else
dates = datesFromQualifier( context, options, 'P585' )
end
if options.qualifiers.P27 then
mw.log('>>>>>>>>>>>>>')
for _, claim in ipairs( options.qualifiers.P27 ) do
if claim and claim.datavalue and claim.datavalue.value and claim.datavalue.value.id then
local categoryOptions = { category = 'P7084[P27:' .. claim.datavalue.value.id .. ']' }
recipientCategory = recipientCategory .. context.extractCategory( categoryOptions, entityId )
end
end
end
end
-- получение ссылки по идентификатору и вывод планки
if image then
local link = mw.wikibase.getSitelink( entityId )
local out = '[[File:' .. image
if border == true then
out = out .. '|border'
end
out = out .. '|' .. size .. '|link='
-- получение ссылки из родительского элемента
-- для степеней обычно только одна общая статья
if not link then
local partOfClaims = WDS.load( entityId, 'P361' ) -- часть от
if not partOfClaims or #partOfClaims == 0 then
partOfClaims = WDS.load( entityId, 'P279' ) -- подкласс от
end
if partOfClaims and #partOfClaims > 0 then
for _, claim in ipairs( partOfClaims ) do
if claim.type == 'statement' and claim.mainsnak.snaktype == 'value' then
link = mw.wikibase.getSitelink( claim.mainsnak.datavalue.value.id )
if link then
break
end
end
end
end
end
if link then
out = out .. link
else
out = out .. 'd:' .. entityId
end
if label then
out = out .. '|' .. label
end
out = out .. ']]'
out = out .. recipientCategory
return out
end
local out = context.formatValueDefault( context, options, statement )
if out and out ~= '' then
if dates ~= '' then
out = out .. ' (' .. dates .. ')'
end
return '<span style="display:inline-block; text-align:left>' .. out .. recipientCategory .. '</span>'
end
return ''
end
--Table for documentation
function p.renderDoc()
local out = {}
for i, awardFields in ipairs( awardsOrder.data ) do
local awardId = awardFields[ 1 ]
local link = '[[d:' .. awardId .. '|' .. awardId .. ']]'
if i == 351 then
-- limits
table.insert( out, '| … || … || … || … || …' )
elseif i > 351 and i < #awardsOrder.data then
-- do nothing
elseif awardId == '-' then
-- separator
table.insert( out, '|' .. i .. '|| colspan="3" | ----' )
else
local image, size, border = p.getImageFromEntity( awardId )
if image then
image = '[[File:' .. image
if border == true then
image = image .. '|border'
end
image = image .. '|' .. size .. ']]'
else
image = ''
end
local label = mw.wikibase.getLabel( awardId ) or ''
local article = mw.wikibase.getSitelink( awardId )
if article then
if label == '' then
label = article
end
label = '[[' .. article .. '|' .. label .. ']]'
end
local countryStatements = mw.wikibase.getBestStatements( awardId, 'P17' )
local countries = {}
if countryStatements then
for _, statement in ipairs( countryStatements ) do
if statement.mainsnak.datavalue and
statement.mainsnak.datavalue.type == 'wikibase-entityid'
then
local countryId = statement.mainsnak.datavalue.value.id
table.insert( countries, mw.wikibase.getLabel( countryId ) )
end
end
end
table.insert( out, '|' .. i .. '||' .. link .. '||' .. image ..
'||' .. label .. '||' .. table.concat( countries, ', ' ) )
end
end
return '{| class="wikitable"\n' ..
'! # !! Элемент !! Планка !! Название !! Государство\n|-\n' ..
table.concat( out, '\n|-\n' ) ..
'\n|}'
end
return p
4de64e0e2181e8a4487f3e18da893fca9f92660d
Шаблон:OnLua
10
227
505
2024-05-07T19:08:37Z
ruwiki>MBH
0
MBH переименовал страницу [[Шаблон:OnLua]] в [[Шаблон:Lua]]
wikitext
text/x-wiki
#перенаправление [[Шаблон:Lua]]
b72371e7ae22239863c474a78238171c2bd94c7e
Шаблон:Lua
10
230
511
2024-05-07T19:08:37Z
ruwiki>MBH
0
MBH переименовал страницу [[Шаблон:OnLua]] в [[Шаблон:Lua]]
wikitext
text/x-wiki
<includeonly>{{ombox
| small = yes
| style = width:23em;
| image = [[Файл:Lua-logo-nolabel.svg|40px|alt=|link=]]
| text = {{replace|Этот шаблон {{#if: {{{partly|}}} | частично }} реализован на основе [[Lua]]{{#if:{{{module2|}}}{{{tech2|}}}|:<br><ul><li>}}{{#if:{{{1|}}}{{{tech|}}}| с использованием {{{tech|{{#if:{{{2|}}}|функции <code>{{#if:{{{line|}}}|[[Module:{{{1}}}#L-{{{line}}}|{{{2}}}()]]|[[{{{funcref|Module:{{{1}}}#{{{2}}}}}}|{{{2}}}()]]}}</code> из }}{{#if:{{{1|}}}|модуля [[Module:{{{1}}}|{{{1}}}]]}}}}};}}<!--
-->{{#invoke:Transclude|npc|OnLua/Строка|
module=
|function=
|tech=
|line=
}}.|;.|.}}{{#if:{{{module2|}}}{{{tech2|}}}|</ul>}} {{#if:{{{1|}}}{{{tech|}}}{{{module1|}}}{{{tech1|}}}||<div class="error"><small>'''Не указано название использующегося модуля!'''</small></div>}}
}}{{#ifeq:{{SUBPAGENAME}}|{{{doc|doc}}}||{{#if:{{{nocat|}}}||[[Категория:Шаблоны, использующие Scribunto]]{{#if:{{{1|}}}{{{tech|}}}{{{module1|}}}{{{tech1|}}}||[[Категория:Шаблоны, использующие Lua, без указания модуля]]}}}}}}</includeonly><noinclude>{{doc}}</noinclude>
f1fdaa87edb15d61e23e98f6e25d171a975e10eb
Шаблон:OnLua/Строка
10
228
507
2024-05-07T19:08:38Z
ruwiki>MBH
0
MBH переименовал страницу [[Шаблон:OnLua/Строка]] в [[Шаблон:Lua/Строка]]
wikitext
text/x-wiki
#перенаправление [[Шаблон:Lua/Строка]]
d7f869ccc7a7efc800399fce32bc75e0f91066de
Шаблон:Lua/Строка
10
231
513
2024-05-07T19:08:38Z
ruwiki>MBH
0
MBH переименовал страницу [[Шаблон:OnLua/Строка]] в [[Шаблон:Lua/Строка]]
wikitext
text/x-wiki
<includeonly>{{#if: {{{module|}}}{{{tech|}}} | <li>с использованием {{#if: {{{tech|}}} | {{{tech}}} | {{#if: {{{function|}}} | {{#if: {{{module|}}} | функции <code>{{#if: {{{line|}}} | [{{fullurl: Module:{{{module}}}|action=edit}}#mw-ce-l{{{line}}} {{{function}}}()] | [[{{{funcref|Module:{{{module}}}#{{{function}}}}}} | {{{function}}}()]]}}</code> из }}}}{{#if: {{{module|}}} | модуля [[Module:{{{module}}} | {{{module}}}]]}}}};}}</includeonly><noinclude>[[Категория:Шаблоны:Подстраницы шаблонов]]</noinclude>
5a35837338c2daee2d240a8e5335e8fec8e7d87e
Шаблон:Wikidata/p569
10
269
699
2024-05-08T19:10:13Z
ruwiki>Dima st bk
0
|suppressAge={{{suppress age|}}} с викиданных
wikitext
text/x-wiki
{{#switch:{{{1|}}}|-=|={{#invoke:Wikidata|formatStatements|property=p569|claim-module=Wikidata/date|claim-function=formatDateOfBirthClaim|nocat={{{nocat|}}}{{NAMESPACE}}|suppressAge={{{suppress age|}}}}}|{{#invoke:Infocards|dateOfBirth|{{{1|}}}|{{{2|}}}|suppressAge={{wikidata|P570|plain=true}}{{{suppress age|}}}|nocat={{{nocat|}}}{{NAMESPACE}}}}}}<noinclude>{{doc}}</noinclude>
9643ab18fcd322831b72e38658b58c6b94a914e2
Шаблон:Установлена проверка на неизвестные параметры
10
296
753
2024-05-10T14:11:21Z
ruwiki>Abiyoyo
0
категория для шаблонов отдельно, для самих категорий отдельно
wikitext
text/x-wiki
{{ombox
|name = Установлена проверка на неизвестные параметры
|text = В этом шаблоне установлена [[Модуль:Check for unknown parameters|проверка на неизвестные параметры]], добавляющая страницы в {{c|{{#if:{{{категория|}}}|{{{категория|}}}|Страницы с неизвестными параметрами шаблона {{ROOTPAGENAME}}}}|В}}.
|type = notice
}}<includeonly>{{no-doc|[[Категория:Шаблоны с установленной проверкой на неизвестные параметры]]{{#ifexist: Категория:{{#if:{{{категория|}}}|{{{категория|}}}|Страницы с неизвестными параметрами шаблона {{ROOTPAGENAME}}}} || [[Категория:Шаблоны с установленной проверкой на неизвестные параметры и несуществующей категорией]] }}|nocat={{{nocat|}}}}}</includeonly><noinclude>{{doc-inline}}
См. [[Модуль:Check for unknown parameters]] и [[:Категория:Википедия:Неизвестные параметры шаблонов]].
Добавляет {{Категория с размером|Шаблоны с установленной проверкой на неизвестные параметры и несуществующей категорией}}.
[[Категория:Шаблоны:Предупреждения]]
[[Категория:Шаблоны:Для документирования шаблонов]]
{{doc-end}}
</noinclude>
cd47e06eec53b65393adba1f3143d6cd3d6cc54c
Модуль:TemplateDataDoc
828
299
759
2024-05-15T20:45:48Z
ruwiki>Abiyoyo
0
для персокарточек
Scribunto
text/plain
require( 'strict' );
local docSubPage = mw.message.new( 'Templatedata-doc-subpage' ):plain();
local p = {};
local lastNumber = 0;
-- Enable/disable additional spacing for block-formatted templates
local formatBlockSpaces = true;
-- Params that should not be shown in code
local deprecatedParams = {
'nocat',
'from',
'nocoord',
'nocatcoord',
'Автооформление заголовка',
'автооформление заголовка',
'Ширина',
'ширина',
'Ширина изображения',
'ширина изображения',
'Ширина логотипа',
'ширина логотипа',
'Ширина автографа',
'ширина автографа',
};
local noDocNote = 'TemplateDataDoc: Запишите страницу для отображения заполненного шаблона.';
function p.processJson( json )
local status, data = pcall( mw.text.jsonDecode, json );
if status == false then
return nil;
end
if not data[ 'paramOrder' ] then
data[ 'paramOrder' ] = {};
for paramName, paramData in pairs( data[ 'params' ] ) do
table.insert( data[ 'paramOrder' ], paramName );
end
end
for _, param in ipairs( deprecatedParams ) do
if data[ 'params' ][ param ] ~= nil then
data[ 'params' ][ param ][ 'deprecated' ] = '-';
end
end
return data;
end
function p.getTemplateData( pageName )
local title = mw.title.makeTitle( 0, pageName );
if not title or not title.exists then
return false
end
local content = title:getContent()
if not content then
return false;
end;
local json = mw.ustring.match( content, '<[Tt]emplate[Dd]ata%s*>(.*)</[Tt]emplate[Dd]ata%s*>' );
if not json then
return nil;
end
return p.processJson( json )
end
function p.getValue( data, key )
if data[ key ] then
return data[ key ];
end
-- Numbered keys return as numbers
local nkey = tonumber( key );
if nkey ~= nil and data[ nkey ] then
return data[ nkey ];
end
return {};
end
-- See https://phabricator.wikimedia.org/diffusion/ETDA/browse/master/Specification.md?as=remarkup
-- We need a global format value for the 'block' and 'inline': [[phab:T205438]]
function p.convertFormatString( rawTemplateFormat )
local formatType = rawTemplateFormat or 'inline';
local templateFormat = formatType;
local isBlockFormatted = false;
if formatType == 'block' then
templateFormat = '{{_\n| _ = _\n}}';
isBlockFormatted = true;
elseif formatType == 'inline' then
templateFormat = '{{_|_=_}}';
end
return templateFormat, isBlockFormatted, formatType;
end
function p.getFormatParts( rawTemplateFormat, templateName )
local templateFormat, isBlockFormatted, formatType = p.convertFormatString( rawTemplateFormat );
local nameFormat = mw.ustring.match( templateFormat, '^[^|]+' );
local paramKeyFormat = mw.ustring.match( templateFormat, '%|[^=]+=' );
local paramValueFormat = mw.ustring.match( templateFormat, '=[^}]+' );
paramValueFormat = mw.ustring.sub( paramValueFormat, 2 );
local endFormat = mw.ustring.match( templateFormat, '%}%}.*$' );
local startFormat = mw.ustring.gsub( nameFormat, '_', templateName );
return isBlockFormatted, formatType, startFormat, endFormat, paramKeyFormat, paramValueFormat;
end
function p.formatKeyValue( key, parameterData, formatData )
if parameterData[ 'deprecated' ] then
return '';
end
local args = formatData.args;
local parameterName = key;
local nkey = tonumber( key );
-- Add additional spacing to string keys
if formatBlockSpaces and formatData.parameterLength and formatData.formatType ~= 'inline' and ( nkey == nil or lastNumber ~= nkey - 1 ) then
while mw.ustring.len( key ) < formatData.parameterLength do
key = key .. ' ';
end
end
-- Remove numbering for adjacent numbered keys
if nkey ~= nil and lastNumber == nkey - 1 then
key = '';
lastNumber = nkey;
end
local value = '';
if formatData.valueKey == 'example' and parameterData[ 'example' ] then
-- Example
value = parameterData[ 'example' ];
else
if formatData.valueKey == 'description' and parameterData[ 'description' ] then
-- Description
value = parameterData[ 'description' ];
if value ~= '' then
value = '<!-- ' .. value .. ' -->';
end
elseif parameterData[ 'autovalue' ] then
-- Autovalue
value = parameterData[ 'autovalue' ];
end
if args[ '$' .. parameterName ] and args[ '$' .. parameterName ] ~= '' then
-- Custom values from template call
value = args[ '$' .. parameterName ];
end
end
local formattedKey = mw.ustring.gsub( formatData.paramKeyFormat, '_+', key, 1 );
if key == '' then
formattedKey = mw.ustring.gsub( formattedKey, '=', '' );
end
return formattedKey .. mw.ustring.gsub( formatData.paramValueFormat, '_', value, 1 );
end
function p.generateBlankCode( templateData, templateName, args )
if templateData == false then
return '{{' .. templateName .. '}}';
end
local parameterLength = 0;
for i, parameterName in ipairs( templateData[ 'paramOrder' ] ) do
local parameterData = p.getValue( templateData[ 'params' ], parameterName );
if not parameterData[ 'deprecated' ] then
local length = mw.ustring.len( parameterName );
if length > parameterLength then
parameterLength = length;
end
end
end
local isBlockFormatted, formatType, startFormat, endFormat, paramKeyFormat, paramValueFormat = p.getFormatParts( templateData[ 'format' ], templateName );
local out = startFormat;
lastNumber = 0;
for i, parameterName in ipairs( templateData[ 'paramOrder' ] ) do
local parameterData = p.getValue( templateData[ 'params' ], parameterName );
if parameterData[ 'inherits' ] then
parameterData = p.getValue( templateData[ 'params' ], parameterData[ 'inherits' ] );
end
out = out .. p.formatKeyValue( parameterName, parameterData, {
args = args,
valueKey = ( args[ 'description' ] and 'description' or nil ),
formatType = formatType,
isBlockFormatted = isBlockFormatted,
parameterLength = parameterLength,
paramKeyFormat = paramKeyFormat,
paramValueFormat = paramValueFormat,
} );
end
return out .. endFormat;
end
function p.generateBlank( frame )
local frame = mw.getCurrentFrame();
local getArgs = require( 'Module:Arguments' ).getArgs;
local args = getArgs( frame );
local templateName = frame.args[ 1 ];
table.remove( args, 1 );
local docPage = 'Template:' .. templateName .. '/' .. docSubPage;
local templateData = p.getTemplateData( docPage );
local out = p.generateBlankCode( templateData, templateName, args );
local previewNote = ''
if templateData == false and frame:preprocess('{{REVISIONID}}') == '' then
previewNote = '<div class="warningbox">' .. noDocNote .. '</div>';
end
return previewNote .. frame:extensionTag{ name = 'pre', content = out };
end
function p.generateExampleCode( templateData, templateName, args )
if templateData == false then
return '{{' .. templateName .. '}}';
end
local parameterLength = 0;
for i, parameterName in ipairs( templateData[ 'paramOrder' ] ) do
local parameterData = p.getValue( templateData[ 'params' ], parameterName );
if parameterData[ 'example' ] and not parameterData[ 'deprecated' ] then
local length = mw.ustring.len( parameterName );
if length > parameterLength then
parameterLength = length;
end
end
end
local isBlockFormatted, formatType, startFormat, endFormat, paramKeyFormat, paramValueFormat = p.getFormatParts( templateData[ 'format' ], templateName );
local out = startFormat;
lastNumber = 0;
for i, parameterName in ipairs( templateData[ 'paramOrder' ] ) do
local parameterData = p.getValue( templateData[ 'params' ], parameterName );
if parameterData[ 'inherits' ] then
parameterData = p.getValue( templateData[ 'params' ], parameterData[ 'inherits' ] );
end
if parameterData[ 'example' ] then
out = out .. p.formatKeyValue( parameterName, parameterData, {
args = args,
valueKey = 'example',
formatType = formatType,
isBlockFormatted = isBlockFormatted,
parameterLength = parameterLength,
paramKeyFormat = paramKeyFormat,
paramValueFormat = paramValueFormat,
} );
end
end
return out .. endFormat;
end
function p.generateExample( frame )
local frame = mw.getCurrentFrame();
local args = frame.args;
local templateName = frame.args[ 1 ];
local docPage = 'Template:' .. templateName .. '/' .. docSubPage;
local templateData = p.getTemplateData( docPage );
local out = p.generateExampleCode( templateData, templateName, args );
local previewNote = ''
if templateData == false and frame:preprocess('{{REVISIONID}}') == '' then
previewNote = '<div class="warningbox">' .. noDocNote .. '</div>';
end
return previewNote .. frame:preprocess( out ) .. frame:extensionTag{ name = 'pre', content = out };
end
return p;
53670b81abac0bc22d720fbe984944dcd709da7c
Шаблон:Скрытый блок/styles.css
10
197
440
2024-05-16T20:54:54Z
ruwiki>Putnik
0
поддержка тёмной темы
sanitized-css
text/css
.ts-Скрытый_блок {
margin: 0;
overflow: hidden;
border-collapse: collapse;
box-sizing: border-box;
font-size: 95%;
}
.ts-Скрытый_блок-title {
text-align: center;
font-weight: bold;
line-height: 1.6em;
min-height: 1.2em;
}
.ts-Скрытый_блок .mw-collapsible-content {
overflow-x: auto;
overflow-y: hidden;
clear: both;
}
.ts-Скрытый_блок::before,
.ts-Скрытый_блок .mw-collapsible-toggle {
padding-top: .1em;
width: 6em;
font-weight: normal;
font-size: calc(90% / 0.95);
}
.ts-Скрытый_блок-rightHideLink .mw-collapsible-toggle {
float: right;
text-align: right;
}
.ts-Скрытый_блок-leftHideLink .mw-collapsible-toggle {
float: left;
text-align: left;
}
.ts-Скрытый_блок-gray {
padding: 2px;
border: 1px solid var(--border-color-base, #a2a9b1);
}
.ts-Скрытый_блок-transparent {
border: none;
}
.ts-Скрытый_блок-gray .ts-Скрытый_блок-title {
background: var(--background-color-neutral, #eaecf0);
padding: .1em 6em;
padding-right: 0;
}
.ts-Скрытый_блок-transparent .ts-Скрытый_блок-title {
background: transparent;
padding: .1em 5.5em;
padding-right: 0;
}
.ts-Скрытый_блок-gray .mw-collapsible-content {
padding: .25em 1em;
}
.ts-Скрытый_блок-transparent .mw-collapsible-content {
padding: .25em 0;
}
.ts-Скрытый_блок-gray.ts-Скрытый_блок-rightHideLink .mw-collapsible-toggle {
padding-right: 1em;
}
.ts-Скрытый_блок-transparent.ts-Скрытый_блок-rightHideLink .mw-collapsible-toggle {
padding-right: 0;
}
.ts-Скрытый_блок-gray.ts-Скрытый_блок-leftHideLink .mw-collapsible-toggle {
padding-left: 1em;
}
.ts-Скрытый_блок-transparent.ts-Скрытый_блок-leftHideLink .mw-collapsible-toggle {
padding-left: 0;
}
.ts-Скрытый_блок-gray.ts-Скрытый_блок-rightHideLink .ts-Скрытый_блок-title-leftTitle {
padding-left: 1em;
}
.ts-Скрытый_блок-gray.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-leftTitle {
padding-left: 6.5em;
}
.ts-Скрытый_блок-gray.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-rightTitle {
padding-right: 1em;
}
.ts-Скрытый_блок-transparent.ts-Скрытый_блок-rightHideLink .ts-Скрытый_блок-title-rightTitle,
.ts-Скрытый_блок-transparent.ts-Скрытый_блок-rightHideLink .ts-Скрытый_блок-title-leftTitle {
padding-left: 0;
}
.ts-Скрытый_блок-transparent.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-rightTitle,
.ts-Скрытый_блок-transparent.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-leftTitle {
padding-right: 0;
}
.ts-Скрытый_блок + .ts-Скрытый_блок,
.ts-Скрытый_блок + link + .ts-Скрытый_блок {
border-top-style: hidden;
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
41e605b205f412804b46a4c6c5dd51a71c6a59ca
Шаблон:Карточка/doc
10
226
503
2024-05-17T22:19:21Z
ruwiki>Abiyoyo
0
дополнение
wikitext
text/x-wiki
{{docpage}}
{{OnLua|Infobox|renderLines|module2=Transclude|function2=npc}}
{{СИШ}}
Это меташаблон для создания [[Википедия:Шаблоны-карточки|шаблонов-карточек]].
== Параметры ==
=== Служебные ===
; имя: Имя шаблона, необходимое для корректной работы служебных инструментов на всех страницах, где используется шаблон. Для простоты можно использовать <code><nowiki>{{subst:PAGENAME}}</nowiki></code>.
; автозаголовки: Указание «да» приводит к автоматическому скрытию заголовков, после которых, вплоть до следующего заголовка, все поля пусты. Возможно использовать фиктивные заголовки «-» для прерывания области скрытия. Будет работать некорректно, если требуется указать два заголовка подряд — например, при использовании многоуровневых заголовков. В этом случае рекомендуется явно указать «нет» на случай смены значения по умолчанию с «нет» на «да».
; from: Указывается элемент Викиданных, из которого берётся информация.
=== Основные ===
; вверху: Текст, отображаемый вверху таблицы. Обычно это название предмета статьи.
; вверху2: Дополнительный текст, отображаемый вверху таблицы. Обычно используется для оригинального названия.
; вверху3: Дополнительный текст, отображаемый вверху таблицы.
; изображение: Изображение, которое будет отображено под основным заголовком в правой части таблицы (правее заголовков/списков). Параметр ''изображение'' допускает стандартный викикод для отображения. Для разных типов параметра можно использовать {{tl|Форматирование изображения}}. Обычно предпочтительнее использовать код <code><nowiki>{{wikidata|P18|{{{изображение|}}}|caption={{{описание изображения|}}}}}</nowiki></code>.
; подпись: Подпись под изображением. Отображается только в том случае, если задано изображение. При использовании {{tlp|wikidata|P18}} не заполняется.
; изображение2: Дополнительное изображение.
; изображение3: Дополнительное изображение.
; заголовок<sub>n</sub>: Используется для создания заголовков в ряду. Этот и следующие 2 параметра работают при n≥1.
; метка<sub>n</sub>: Используется для подписи текста
; текст<sub>n</sub>: Используется для принятия параметров в специализированных шаблонах-карточках.
; блок<sub>n</sub>: Технический параметр, используется для вставки блоков, заключённых в <tr>, таких как {{t|карточка/блок}}.
; викиданные<sub>n</sub>: Подставляет значение из указанного параметра [[Википедия:Викиданные|Викиданных]] в поле текста, если текст в этой строке определён. Если в поле текста передано значение <code>-</code>, то значение из Викиданных будет скрыто.
; внизу
; внизу<sub>n</sub>: Ячейка во всю ширину таблицы, располагающаяся внизу тела шаблона (то есть под заголовками/метками и текстом).
=== Стили ===
; цвет: Применяется для автоматической раскраски полей «вверху», «внизу» и заголовков через CSS при помощи цветовых тем, имеющихся в шаблоне {{t|Цвет}}
; стиль_тела: Применяется ко всей карточке, обычно используется для указания её ширины, например, <code>width:23em;</code>
; стиль_вверху: Применяется к полю «вверху», например, для указания цвета фона или изменения размера шрифта: <code>font-size:medium;</code>
; стиль_вверху<sub>n</sub>: Используется для изменения стиля дополнительного текста вверху таблицы, например, чтобы убрать курсивное начертание: <code>font-style:normal;</code>
; стиль_изображения: Применяется к ячейке, в которой располагается изображение и его описание
; стиль_изображения<sub>n</sub>: Применяется к ячейке, в которой располагается дополнительное изображение
; стиль_подписи: Применяется к подписи изображения
; стиль_заголовков: С помощью этого стиля можно настроить отображение заголовков, в частности, указать цвет фона: <code>background: #a3eea3;</code>
; стиль_заголовка<sub>n</sub>: Применяется к конкретному заголовку в строке n
; стиль_меток: Применяется к меткам
; стиль_метки<sub>n</sub>: Применяется к конкретной метке в строке n
; стиль_текста: Применяется к тексту
; стиль_текста<sub>n</sub>: Применяется к конкретному тексту в строке n
; стиль_внизу: Эти стили применяются не только в первому ''внизу'', но и ко всем остальным — в отличие от ''стиль_вверху''.
; стиль_внизу<sub>n</sub>: CSS-стили, которые должны быть применены к нижним (указанными параметрами ''внизу'' и ''внизу<sub>n</sub>'') ячейкам.
== Возможности ==
=== Сдвоенные ячейки ===
Если для параметра <code>текст<sub>n</sub></code> значение <code>метка<sub>n</sub></code> не определено, то <code>текст<sub>n</sub></code> автоматически расширяется до 2 ячеек. Для выравнивания по левой стороне можно использовать следующий код:
<pre><nowiki>
|текст2 = {{{параметр|}}}
|стиль_текста2 = text-align:left;
</nowiki></pre>
=== Необязательные ячейки ===
Ряд с меткой, но без текста не будет отображён. Это позволяет легко создавать необязательные параметры в специализированных шаблонах-карточках. Для создания опциональной ячейки используйте параметр следующим образом:
<pre><nowiki>
|метка5 = Население
|текст5 = {{{население|}}}
</nowiki></pre>
Таким образом, если параметр <code>население</code> не будет определён, строка «Население» не будет отображена.
=== Необязательные заголовки ===
Таким же образом можно организовать необязательные заголовки. Следующий пример будет выводить заголовок «Структура», если задан хотя бы один из параметров <code>содержимое</code>, <code>размещение</code>:
<pre><nowiki>
|заголовок5 = {{#if:{{{содержимое|}}}{{{размещение|}}}|Структура}}
|метка6 = Содержимое
|текст6 = {{{содержимое|}}}
|метка7 = Размещение
|текст7 = {{{размещение|}}}
</nowiki></pre>
Если есть заголовокN, то текстN и меткаN игнорируются. Если нет заданного заголовкаN, то показываются текстN и меткаN.
{|
|-
|<pre><nowiki>
|заголовок1 = {{{заголовок1|}}}
|метка1 = {{{метка1|}}}
|текст1 = {{{текст1|}}}
</nowiki></pre>
|}
{|
|-
|<pre><nowiki>
|заголовок1 = заголовок_текст
|метка1 = метка_текст
|текст1 = текст_текст
</nowiki></pre>
|
{| class="wikitable"
|-
! заголовок_текст
|}
|<pre><nowiki>
|заголовок1 =
|метка1 = метка_текст
|текст1 = текст_текст
</nowiki></pre>
|
{| class="wikitable"
|-
| метка_текст|| текст_текст
|}
|}
=== Оформление параметров ===
Для оформления параметра можно использовать [[Википедия:Функции парсера##if|функцию парсера «#if»]]. Например, следующие строки добавят к параметру <code>текст6</code> подпись кг, если этот параметр определён:
<pre><nowiki>
|метка6 = Масса
|текст6 = {{#if:{{{масса|}}} |{{{масса}}} кг}}
</nowiki></pre>
А расстановку ссылок на страницы можно организовать с помощью «[[Википедия:Функции парсера##switch:|#switch]]», например:
<pre><nowiki>
|метка6 = Раса
|текст6 = {{#switch:{{{раса|}}}
|Европеоиды = [[Европеоидная раса|Европеоиды]]
|Негроиды = [[Негроидная раса|Негроиды]]
|Монголоиды = [[Монголоидная раса|Монголоиды]]
|{{{раса|}}}
}}
</nowiki></pre>
== Пустой шаблон ==
<pre>
{{Карточка
|имя = {{subst:PAGENAME}}
|автозаголовки = да
|стиль_вверху =
|стиль_заголовков =
|стиль_внизу =
|вверху =
|вверху2 =
|изображение =
|заголовок1 =
|метка2 =
|текст2 =
|викиданные2 =
|метка3 =
|текст3 =
|викиданные3 =
|метка4 =
|текст4 =
|викиданные4 =
|метка5 =
|текст5 =
|викиданные5 =
|метка6 =
|текст6 =
|викиданные6 =
|метка7 =
|текст7 =
|викиданные7 =
|метка8 =
|текст8 =
|викиданные8 =
|метка9 =
|текст9 =
|викиданные9 =
|метка10 =
|текст10 =
|викиданные10 =
...
|меткаN =
|текстN =
|викиданныеN =
|внизу =
}}<noinclude>
{{doc}}
</noinclude></pre>
{{скрытый|Заголовок=11-20|Содержание=<pre>
|метка11 =
|текст11 =
|викиданные11 =
|метка12 =
|текст12 =
|викиданные12 =
|метка13 =
|текст13 =
|викиданные13 =
|метка14 =
|текст14 =
|викиданные14 =
|метка15 =
|текст15 =
|викиданные15 =
|метка16 =
|текст16 =
|викиданные16 =
|метка17 =
|текст17 =
|викиданные17 =
|метка18 =
|текст18 =
|викиданные18 =
|метка19 =
|текст19 =
|викиданные19 =
|метка20 =
|текст20 =
|викиданные20 =
</pre>}}
{{скрытый||Заголовок=21-30|Содержание=<pre>
|метка21 =
|текст21 =
|викиданные21 =
|метка22 =
|текст22 =
|викиданные22 =
|метка23 =
|текст23 =
|викиданные23 =
|метка24 =
|текст24 =
|викиданные24 =
|метка25 =
|текст25 =
|викиданные25 =
|метка26 =
|текст26 =
|викиданные26 =
|метка27 =
|текст27 =
|викиданные27 =
|метка28 =
|текст28 =
|викиданные28 =
|метка29 =
|текст29 =
|викиданные29 =
|метка30 =
|текст30 =
|викиданные30 =
</pre>}}
{{скрытый||Заголовок=31-40|Содержание=<pre>
|метка31 =
|текст31 =
|викиданные31 =
|метка32 =
|текст32 =
|викиданные32 =
|метка33 =
|текст33 =
|викиданные33 =
|метка34 =
|текст34 =
|викиданные34 =
|метка35 =
|текст35 =
|викиданные35 =
|метка36 =
|текст36 =
|викиданные36 =
|метка37 =
|текст37 =
|викиданные37 =
|метка38 =
|текст38 =
|викиданные38 =
|метка39 =
|текст39 =
|викиданные39 =
|метка40 =
|текст40 =
|викиданные40 =
</pre>}}
{{скрытый||Заголовок=41-50|Содержание=<pre>
|метка41 =
|текст41 =
|викиданные41 =
|метка42 =
|текст42 =
|викиданные42 =
|метка43 =
|текст43 =
|викиданные43 =
|метка44 =
|текст44 =
|викиданные44 =
|метка45 =
|текст45 =
|викиданные45 =
|метка46 =
|текст46 =
|викиданные46 =
|метка47 =
|текст47 =
|викиданные47 =
|метка48 =
|текст48 =
|викиданные48 =
|метка49 =
|текст49 =
|викиданные49 =
|метка50 =
|текст50 =
|викиданные50 =
</pre>}}
{{скрытый||Заголовок=51-60|Содержание=<pre>
|метка51 =
|текст51 =
|викиданные51 =
|метка52 =
|текст52 =
|викиданные52 =
|метка53 =
|текст53 =
|викиданные53 =
|метка54 =
|текст54 =
|викиданные54 =
|метка55 =
|текст55 =
|викиданные55 =
|метка56 =
|текст56 =
|викиданные56 =
|метка57 =
|текст57 =
|викиданные57 =
|метка58 =
|текст58 =
|викиданные58 =
|метка59 =
|текст59 =
|викиданные59 =
|метка60 =
|текст60 =
|викиданные60 =
</pre>}}
== Примерный шаблон для карточки персоны ==
<pre>{{Карточка
|имя = {{subst:PAGENAME}}
|автозаголовки = да
|стиль_вверху =
|стиль_заголовков =
|стиль_внизу =
|вверху = {{карточка/имя|{{{имя|}}}}}
|вверху2 = {{карточка/оригинал имени|{{{оригинал имени|}}}}}
|изображение = {{wikidata|p18|{{{фото|}}}|caption={{{описание изображения|}}}|size={{{ширина|}}}}}
|метка1 = Имя при рождении
|текст1 = {{{имя при рождении|}}}
|викиданные1 = p1477
|метка2 = Дата рождения
|текст2 = {{wikidata/p569|{{{дата рождения|}}}|{{{дата смерти|}}}}}
|метка3 = Место рождения
|текст3 = {{{место рождения|}}}
|викиданные3 = p19
|метка4 = Дата смерти
|текст4 = {{wikidata/p570|{{{дата смерти|}}}|{{{дата рождения|}}}}}
|метка5 = Место смерти
|текст5 = {{{место смерти|}}}
|викиданные5 = p20
|метка6 = Гражданство
|текст6 = {{{гражданство|}}}
|викиданные6 = p27
|метка7 = Сценические имена / Прозвище
|текст7 = {{{прозвище|}}}
|викиданные7 = p1449
|заголовок8 = {{wikidata|p856|{{{сайт|}}}}}
|внизу = {{карточка/Викисклад|{{{викисклад|}}}}}
}}</pre>
Шаблоны {{tl|wikidata/p569}} и {{tl|wikidata/p570}} работают с датами по юлианскому календарю следующим образом:
* <code>13.5.1801 (1)</code> будет отображено как [[13 мая|1 (13) мая]] [[1801 год|1801]];
* <code>12.6.1801 (31.5)</code> будет отображено как 31 мая ([[12 июня]]) [[1801 год|1801]];
* <code>12.1.1802 (31.12.1801)</code> будет отображено как 31 декабря 1801 ([[12 января]] [[1802 год|1802]]).
== Отслеживающие категории, подставляемые шаблоном ==
{{Дерево категорий|Отслеживающие категории:Шаблон:Карточка||1|title=}}
== См. также ==
* [[Википедия:Шаблоны-карточки]]
* {{t|Универсальная карточка}}
* {{t|Навигационная таблица}} — для создания горизонтальных навигационных таблиц (предпочтительнее вертикальных, иногда делаемых на карточке)
* [[:Категория:Шаблоны:Подстраницы шаблона Карточка|Подстраницы шаблона Карточка]]
* [[Участник:Jack who built the house/alignTemplateParameters.js]]
{{Подстраницы шаблона Карточка}}
<includeonly>
[[Категория:Шаблоны-карточки|*]]
[[Категория:Шаблоны:Мета-шаблоны]]
</includeonly>
f1b3e8ad443b38b993ae6112a8adda8827efe76f
Шаблон:Дерево категорий
10
229
509
2024-05-17T22:35:29Z
ruwiki>QBA-bot
0
Защитил страницу [[Шаблон:Дерево категорий]]: критический шаблон или модуль (каскадная защита) ([Редактирование=только автоподтверждённые] (бессрочно) [Переименование=только автоподтверждённые] (бессрочно))
wikitext
text/x-wiki
<div>{{{title|'''Дерево категорий'''}}}
{{#tag: categorytree| {{#if:{{{1|}}}|{{{1}}}|{{PAGENAME}}}}
| mode = {{#if:{{{2}}}|"{{#ifeq:{{{2}}}|всё|all|{{#ifeq:{{{2}}}|страницы|pages|{{#ifeq:{{{2}}}|категории|categories|{{{2}}}}}}}}}"}}
| depth = {{#if:{{{3}}}|{{{3}}}}}
}}
</div><noinclude>
{{doc}}
</noinclude>
9763d532ff7b79a638abe485875db984254b57db
Шаблон:Заглавная/Шапка
10
6
13
2024-05-18T12:48:35Z
ruwiki>Putnik
0
некрасиво разбивается на строки в новом Векторе
wikitext
text/x-wiki
<noinclude><templatestyles src="Шаблон:Заглавная/styles.css" /></noinclude>
<templatestyles src="Шаблон:Заглавная/Шапка/styles.css" />
<div class="main-block main-top">
<div class="main-top-left">
<h1 class="main-top-header">Добро пожаловать в [[Википедия|Википедию]],</h1>
[[Свободный контент|свободную энциклопедию]], которую [[Справка:Введение в Википедию|может редактировать каждый]].
<div class="main-top-mobileSearch"><span class="main-top-mobileSearchButton skin-minerva-search-trigger">[[Special:Search|Искать среди {{NUMBEROFARTICLES}} {{plural:{{NUMBEROFARTICLES}}|статьи|статей}}]]</span></div>
</div>
<div class="main-top-right main-plainlist">
<p class="main-top-articleCount">Сейчас в Википедии '''[[Special:Statistics|{{NUMBEROFARTICLES}} {{plural:{{NUMBEROFARTICLES}}|статья|статьи|статей}}]]''' на [[Русский язык|русском языке]].</p>
<ul>
<li class="main-top-createArticle">{{Заглавная/Кнопка|Википедия:Мастер статей|Создать статью}}</li>
<li>{{Заглавная/Кнопка|Википедия:Справка|Справка|class=mw-ui-quiet}}</li>
<li>{{Заглавная/Кнопка|Портал:Обзор|Порталы|class=mw-ui-quiet}}</li>
</ul>
</div>
</div><noinclude>
[[Категория:Шаблоны:Подстраницы шаблонов|Заглавная]]
[[Категория:Шаблоны, используемые на Заглавной странице]]
</noinclude>
824063451cf8a6bfd68477221e98b721c54adfe9
Модуль:Message box/ambox.css
828
209
466
2024-05-18T12:53:45Z
ruwiki>Putnik
0
цвета я всё-таки верну
sanitized-css
text/css
/* Скопировано из [[:en:Module:Message box/ambox.css]] с изменениями */
.ambox {
border: 1px solid var(--border-color-base, #a2a9b1);
/* @noflip */
border-left: 10px solid #36c; /* Default "notice" blue */
background: var(--background-color-neutral-subtle, #f8f9fa);
box-sizing: border-box;
margin: 0 10%;
}
/* Не ухудшаем стили для Минервы */
html body.mediawiki.skin-minerva .ambox {
border-width: 0 0 0 4px;
}
/* Single border between stacked boxes. Take into account base templatestyles,
* user styles, and Template:Dated maintenance category.
* remove link selector when T200206 is fixed
*/
.ambox + link + .ambox,
.ambox + link + style + .ambox,
.ambox + link + link + .ambox,
/* TODO: raise these as "is this really that necessary???". the change was Dec 2021 */
.ambox + .mw-empty-elt + link + .ambox,
.ambox + .mw-empty-elt + link + style + .ambox,
.ambox + .mw-empty-elt + link + link + .ambox {
margin-top: -1px;
}
/* For the "small=left" option. */
/* must override .ambox + .ambox styles above */
html body.mediawiki .ambox.mbox-small-left {
/* @noflip */
margin: 4px 1em 4px 0;
overflow: hidden;
width: 238px;
border-collapse: collapse;
font-size: 88%;
line-height: 1.25em;
}
.ambox-speedy {
/* @noflip */
border-left: 10px solid var(--border-color-error, #b32424); /* Red */
background-color: var(--background-color-error-subtle, #fee7e6); /* Pink */
}
.ambox-delete {
/* @noflip */
border-left: 10px solid var(--border-color-error, #b32424); /* Red */
}
.ambox-content {
/* @noflip */
border-left: 10px solid #f28500; /* Orange */
}
.ambox-style {
/* @noflip */
border-left: 10px solid var(--color-warning, #edab00); /* Yellow */
}
.ambox-good {
/* @noflip */
border-left: 10px solid #66cc44;
}
.ambox-discussion {
/* @noflip */
border-left: 10px solid #339966;
}
.ambox-merge {
/* @noflip */
border-left: 10px solid #9932cc;
}
.ambox-move {
/* @noflip */
border-left: 10px solid #9932cc; /* Purple */
}
.ambox-protection {
/* @noflip */
border-left: 10px solid #a2a9b1; /* Gray-gold */
}
.ambox .mbox-text {
border: none;
/* @noflip */
padding: 0.25em 0.5em;
width: 100%;
}
.ambox .mbox-image {
border: none;
/* @noflip */
padding: 2px 0 2px 0.5em;
text-align: center;
}
.ambox .mbox-imageright {
border: none;
/* @noflip */
padding: 2px 0.5em 2px 0;
text-align: center;
}
/* An empty narrow cell */
.ambox .mbox-empty-cell {
border: none;
padding: 0;
width: 1px;
}
.ambox .mbox-image-div {
width: 52px;
}
/* Хак, TODO: посмотреть, как оно на самом деле работает */
.ambox .mbox-textsmall-div {
font-size: 90%;
}
/* Hack around MobileFrontend being opinionated */
html.client-js body.skin-minerva .mbox-text-span {
margin-left: 23px !important;
}
/* Стили нотификаций для ноутбуков */
@media (max-width: 1366px) {
.ambox {
margin-left: 6%;
margin-right: 6%;
}
}
/* Стили нотификаций для мобильного устройсва */
@media (max-width: 719px) {
.ambox {
margin-left: 0;
margin-right: 0;
}
}
/* [[Категория:Модули:Подстраницы CSS]] */
1d03f5efb7ec589bb5edde009c3ae9ef13460e7e
Шаблон:Политик
10
259
679
2024-05-23T21:34:43Z
ruwiki>Abiyoyo
0
в пользу сортировки по изображениям
wikitext
text/x-wiki
{{Карточка
|имя = Политик
|from = {{{from|}}}
|стиль_меток = min-width:9em;
|вверху = {{карточка/имя|{{{имя|{{{Имя|}}}}}}|from={{{from|}}}}}
|вверху2 = {{карточка/оригинал имени|{{{оригинал имени|{{{Оригинал имени|}}}}}}|from={{{from|}}}}}
|изображение = {{wikidata|p18|{{{изображение|{{{Изображение|}}}}}}|size={{{ширина|{{{Ширина|}}}}}}|caption={{{описание изображения|{{{Описание изображения|}}}}}}|from={{{from|}}}}}
|метка1 = Имя при рождении
|текст1 = {{{имя при рождении|{{{Имя при рождении|}}}}}}
|метка2 = Псевдонимы
|текст2 = {{{псевдонимы|{{{Псевдонимы|}}}}}}
|метка3 = Дата рождения
|текст3 = {{wikidata/p569|{{{дата рождения|{{{Дата рождения|}}}}}}|{{{дата смерти|{{{Дата смерти|}}}}}}|from={{{from|}}}}}
|метка4 = Место рождения
|текст4 = {{{место рождения|{{{Место рождения|}}}}}}
|викиданные4 = p19
|метка5 = Дата смерти
|текст5 = {{wikidata/p570|{{{дата смерти|{{{Дата смерти|}}}}}}|{{{дата рождения|{{{Дата рождения|}}}}}}|from={{{from|}}}}}
|метка6 = Место смерти
|текст6 = {{{место смерти|{{{Место смерти|}}}}}}
|викиданные6 = p20
|метка7 = Гражданство
|текст7 = {{{страна|{{{гражданство|{{{подданство|{{{Гражданство|}}}}}}}}}}}}
|викиданные7 = p27
|метка8 = Род деятельности
|текст8 = {{{род деятельности|{{{Род деятельности|}}}}}}
|викиданные8 = p106
|метка9 = Образование
|текст9 = {{{образование|{{{альма-матер|{{{Образование|}}}}}}}}}
|викиданные9 = p69
|метка10 = Учёная степень
|текст10 = {{{учёная степень|{{{Учёная степень|}}}}}}
|викиданные10 = p512
|метка11 = Учёное звание
|текст11 = {{{учёное звание|{{{Учёное звание|}}}}}}
|метка12 = Вероисповедание
|текст12 = {{{вероисповедание|{{{Вероисповедание|}}}}}}
|викиданные12 = p140
|метка13 = Партия
|текст13 = {{{партия|{{{Партия|}}}}}}
|викиданные13 = p102
|метка14 = Основные идеи
|текст14 = {{{основные идеи|{{{Основные идеи|}}}}}}
|викиданные14 = p1142
|метка15 = Отец
|текст15 = {{{отец|{{{Отец|}}}}}}
|викиданные15 = p22
|метка16 = Мать
|текст16 = {{{мать|{{{Мать|}}}}}}
|викиданные16 = p25
|метка17 = {{wikidata gender switch||Супруг|Супруга|Супруг(а)}}
|текст17 = {{wikidata|p26|{{#if: {{{супруга|{{{Супруга|}}}}}} | {{{супруга|{{{Супруга|}}}}}} | {{{супруг|{{{Супруг|}}}}}} }}}}
|метка18 = Дети
|текст18 = {{{дети|{{{Дети|}}}}}}
|викиданные18 = p40
|метка19 = Награды
|текст19 = {{{награды|{{{награды и премии|{{{Награды|}}}}}}}}}
|викиданные19 = p166
|метка20 = Автограф
|текст20 = {{wikidata|p109|{{{автограф|{{{Автограф|}}}}}}|size={{#if:{{{ширина автографа|{{{Ширина автографа|}}}}}}|{{{ширина автографа|{{{Ширина автографа}}}}}}|143x143}}|alt=Автограф|from={{{from|}}}}}
|внизу = {{wikidata|p856|{{{сайт|{{{Сайт|}}}}}}|from={{{from|}}}}}
|внизу2 = {{карточка/Викисклад|{{{викисклад|{{{Викисклад|}}}}}}|from={{{from|}}}}}
}}<!--
-->{{#if:{{NAMESPACE}}{{{nocat|}}}||<!--
-->[[Категория:Персоналии по алфавиту]]<!--
-->[[Категория:Политики по алфавиту]]<!--
-->{{#invoke:Wikidata/category|categorizeIfNoParams}}<!--
-->{{#invoke:CategoryForProfession|mainFunction}}<!--
-->{{Сортировка: по изображениям|{{{изображение|{{{Изображение|}}}}}}|from={{{from|}}}|nocat={{{nocat|}}}|default-type=человек|default-occupation=политик}}<!--
-->}}<!--
-->{{#invoke:check for unknown parameters|check
| unknown = {{#if: {{NAMESPACE}} || [[Категория:Страницы с неизвестными параметрами шаблона Политик|_VALUE_]] }}
| ignoreblank =
| preview = <span class="error">Неизвестный параметр «_VALUE_» шаблона Политик</span>
| showblankpositional= 1
|from|nocat|Автограф|Вероисповедание|Викисклад|Гражданство|Дата рождения|Дата смерти|Дети|Изображение|Имя|Имя при рождении|Мать|Место рождения|Место смерти|Награды|Образование|Описание изображения|Оригинал имени|Основные идеи|Отец|Партия|Псевдонимы|Род деятельности|Сайт|Супруг|Супруга|Учёная степень|Учёное звание|Ширина|Ширина автографа<!--
-->|автограф|вероисповедание|викисклад|гражданство|дата рождения|дата смерти|дети|изображение|имя|имя при рождении|мать|место рождения|место смерти|награды|образование|описание изображения|оригинал имени|основные идеи|отец|партия|псевдонимы|род деятельности|сайт|супруг|супруга|учёная степень|учёное звание|ширина|ширина автографа |альма-матер|страна|подданство|награды и премии
}}<!--
--><noinclude>{{doc}}</noinclude>
6e99fb4d8a3ec44096ba8d60276e31241c0d8f65
Модуль:Message box/fmbox.css
828
225
498
2024-06-03T18:54:56Z
ruwiki>Putnik
0
поддержка тёмной темы
sanitized-css
text/css
/* Скопировано из [[:en:Module:Message box/fmbox.css]] с изменениями */
.fmbox {
clear: both;
margin: 0.2em 0;
width: 100%;
border: 1px solid var(--border-color-base, #a2a9b1);
background-color: var(--background-color-neutral-subtle, #f8f9fa); /* Default "system" gray */
box-sizing: border-box;
}
.fmbox-warning {
border: 1px solid #bb7070; /* Dark pink */
background-color: #ffdbdb; /* Pink */
}
.fmbox-editnotice {
background-color: transparent;
}
.fmbox .mbox-text {
border: none;
/* @noflip */
padding: 0.25em 0.9em;
width: 100%;
}
.fmbox .mbox-image {
border: none;
/* @noflip */
padding: 2px 0 2px 0.9em;
text-align: center;
}
.fmbox .mbox-imageright {
border: none;
/* @noflip */
padding: 2px 0.9em 2px 0;
text-align: center;
}
.fmbox .mbox-invalid-type {
text-align: center;
}
/* Хак, TODO: посмотреть, как оно на самом деле работает */
.fmbox .mbox-textsmall-div {
font-size: 90%;
}
/* [[Категория:Модули:Подстраницы CSS]] */
313e9f5515a4f12a2a44d6c8d57f74cbda4bb464
Модуль:Wikidata/date
828
280
721
2024-06-10T15:24:01Z
ruwiki>Stjn
0
необъявленная глобальная переменная
Scribunto
text/plain
--settings
local nowLabel = 'наст. время'
local moduleDates = require( "Module:Dates" )
local moduleWikidata = require( "Module:Wikidata" )
local dateCat = require("Module:Infocards/dateCat")
-- FIXME: undeclared global variable, used 3 times
local infoclass
local function deepcopy(orig)
local orig_type = type(orig)
local copy
if orig_type == 'table' then
copy = {}
for orig_key, orig_value in next, orig, nil do
copy[deepcopy(orig_key)] = deepcopy(orig_value)
end
setmetatable(copy, deepcopy(getmetatable(orig)))
else -- number, string, boolean, etc
copy = orig
end
return copy
end
local function ageImpl ( bStructure, bPrecision, dStructure, dPrecision )
if ( not bStructure or not dStructure or bPrecision < 10 or dPrecision < 10 ) then
return nil
end
local shift = 0
if ( bStructure.year < 0 and dStructure.year > 0 ) then
shift = -1
end
if ( bPrecision == 10 or dPrecision == 10 ) then
if ( bStructure.month < dStructure.month ) then
return dStructure.year - bStructure.year + shift
end
if ( bStructure.month == dStructure.month ) then
return nil
end
if ( bStructure.month > dStructure.month ) then
return dStructure.year - bStructure.year - 1 + shift
end
end
if ( bStructure.month < dStructure.month ) then
return dStructure.year - bStructure.year + shift
end
if ( bStructure.month == dStructure.month ) then
if ( bStructure.day <= dStructure.day ) then
return dStructure.year - bStructure.year + shift
else
return dStructure.year - bStructure.year - 1 + shift
end
end
if ( bStructure.month > dStructure.month ) then
return dStructure.year - bStructure.year - 1 + shift
end
return nil
end
-- accepts table of time+precision values
local function ageCurrent ( bTable )
local possibleAge = "NYA" -- it means "Not Yet Assigned", not what you imagined!
for bKey, bValue in pairs(bTable) do
if ( bValue.unknown ) then
return nil
end
local bStructure = bValue.structure
local bPrecision = bValue.precision
local dStructure = os.date( "*t" )
local calculatedAge = ageImpl ( bStructure, bPrecision, dStructure, 11 )
if ( possibleAge == "NYA" ) then
possibleAge = calculatedAge
else
if ( possibleAge ~= calculatedAge ) then
possibleAge = nil
end
end
end
return possibleAge
end
-- accepts tables of time+precision values
local function age ( bTable, dTable )
local possibleAge = "NYA" -- it means "Not Yet Assigned", not what you imagined!
for bKey, bValue in pairs( bTable ) do
if ( bValue.unknown ) then
return nil
end
local bStructure = bValue.structure
local bPrecision = bValue.precision
for dKey, dValue in pairs( dTable ) do
if ( dValue.unknown ) then
return nil
end
local dStructure = dValue.structure
local dPrecision = dValue.precision
if ( bValue.calendar == 'julian' and dValue.calendar == 'gregorian' ) then
-- to calculate age, need to adjust bStructure to gregorian calendar
local shift = math.floor(bStructure.year/100-2) - math.floor(bStructure.year/400)
-- TODO: re-implement this properly
bStructure.day = bStructure.day + shift
end
local calculatedAge = ageImpl ( bStructure, bPrecision, dStructure, dPrecision )
if ( possibleAge == "NYA" ) then
possibleAge = calculatedAge
else
if ( possibleAge ~= calculatedAge ) then
possibleAge = nil
end
end
end
end
return possibleAge
end
local function parseISO8601Date(str)
local pattern = "(%-?%d+)%-(%d+)%-(%d+)T"
local Y, M, D = mw.ustring.match( str, pattern )
return tonumber(Y), tonumber(M), tonumber(D)
end
local function parseISO8601Time(str)
local pattern = "T(%d+):(%d+):(%d+)%Z"
local H, M, S = mw.ustring.match( str, pattern)
return tonumber(H), tonumber(M), tonumber(S)
end
local function parseISO8601Offset(str)
if str:sub(-1)=="Z" then return 0,0 end -- ends with Z, Zulu time
-- matches ±hh:mm, ±hhmm or ±hh; else returns nils
local pattern = "([-+])(%d%d):?(%d?%d?)$"
local sign, oh, om = mw.ustring.match( str, pattern)
sign, oh, om = sign or "+", oh or "00", om or "00"
return tonumber(sign .. oh), tonumber(sign .. om)
end
local function parseISO8601(str)
if 'table' == type(str) then
if str.args and str.args[1] then
str = '' .. str.args[1]
else
return 'unknown argument type: ' .. type( str ) .. ': ' .. table.tostring( str )
end
end
local Y,M,D = parseISO8601Date(str)
local h,m,s = parseISO8601Time(str)
local oh,om = parseISO8601Offset(str)
if not Y or not M or not D or not h or not m or not s or not oh or not om then
return nil
end
return tonumber(os.time({year=Y, month=M, day=D, hour=(h+oh), min=(m+om), sec=s}))
end
local function parseClaim ( claim )
if ( claim.mainsnak.snaktype == "value" ) then
local timeISO8601 = string.gsub( string.gsub( tostring( claim.mainsnak.datavalue.value.time ), '-00%-', '-01-' ), '-00T', '-01T' )
local unixtime = parseISO8601( timeISO8601 )
local structure = os.date("*t", unixtime)
local precision = tonumber( claim.mainsnak.datavalue.value.precision )
local calendarmodel = 'gregorian'
if (mw.ustring.find(claim.mainsnak.datavalue.value.calendarmodel, 'Q1985786', 1, true)) then
calendarmodel = 'julian'
end
local item = { structure=structure, precision=precision, calendar = calendarmodel }
return item
elseif ( claim.mainsnak.snaktype == "novalue" ) then
-- novalue
return { unknown="novalue" }
else
--unknown
return { unknown="unknown" }
end
end
-- returns table of time+precision values for specified property
local function parseProperty ( context, options, propertyId )
if ( not context ) then error( 'context not specified'); end
if ( not options ) then error( 'options not specified'); end
if ( not options.entity ) then error( 'options.entity is missing'); end
if ( not propertyId ) then error( 'propertyId not specified'); end
local claims = context.selectClaims( options, propertyId )
if not claims then
return nil
end
local result = {}
for key, claim in pairs( claims ) do
table.insert ( result, parseClaim( claim ) )
end
return result
end
-- проверка на совпадающие даты с разной моделью календаря
local function checkDupDates( t )
if #t > 1 then
local removed = false
local j = 1
-- проверка на совпадающие даты с разной моделью календаря
while (j <= #t) do
local i = 1
while (i <= #t) do
if i ~= j then
if (os.time(t[j].structure) == os.time(t[i].structure)) then
if ((t[j].calendarmodel == 'gregorian') and
(t[i].calendarmodel == 'julian')) then
removed = true
break
else
table.remove(t, i)
end
else
i = i + 1
end
else
i = i + 1
end
end
if removed then
removed = false
table.remove(t, j)
else
j = j+1
end
end
end
end
-- returns first qualifier of specified propertyId
local function getQualifierWithDataValue( statement, qualifierPropertyId )
if ( statement.qualifiers
and statement.qualifiers[qualifierPropertyId] ) then
local qualifiers = statement.qualifiers[qualifierPropertyId]
for _, qualifier in ipairs( qualifiers ) do
if (qualifier.datavalue) then
return qualifier
end
end
end
return nil
end
local p = {}
local function formatDecade( time, categoryNamePrefix )
local bce = ''
local year
if time.year < 0 then
bce = ' до н. э.'
year = math.floor( math.abs( time.year ) / 10 ) * 10
else
year = math.floor( time.year / 10 ) * 10
end
local unit = '-е'
if isGenitive then
unit = '-х'
end
local value = '' .. year .. unit .. bce
if categoryNamePrefix then
return value .. '[[Category:' .. categoryNamePrefix .. ' в ' .. year .. '-е годы' .. bce .. ']]'
end
return value
end
local function formatCentury( time, categoryNamePrefix, isGenitive )
local moduleRoman = require( 'Module:RomanNumber' )
local bce = ''
local century
if time.year < 0 then
bce = ' до н. э.'
century = math.floor( ( math.abs( time.year ) - 1 ) / 100 ) + 1
else
century = math.floor( ( time.year - 1 ) / 100 ) + 1
end
local unit = 'век'
if isGenitive then
unit = 'века'
end
local infix = ' в '
if century == 2 then
infix = ' во '
end
if moduleRoman then
century = moduleRoman.toRomanNumber( century )
end
local value = '[[' .. century .. ' век' .. bce .. '|' .. century .. ' ' .. unit .. bce .. ']]'
if categoryNamePrefix then
return value .. '[[Category:' .. categoryNamePrefix .. infix .. century .. ' веке' .. bce .. ']]'
end
return value
end
local function formatMillenium( time, categoryNamePrefix, isGenitive )
local bce = ''
local millenium
if time.year < 0 then
bce = ' до н. э.'
millenium = math.floor( ( math.abs( time.year ) - 1 ) / 1000 ) + 1
else
millenium = math.floor( ( time.year - 1 ) / 1000 ) + 1
end
local unit = '-е тысячелетие'
if isGenitive then
unit = '-го тысячелетия'
end
local value = '[[' .. millenium .. '-е тысячелетие' .. bce .. '|' .. millenium .. unit .. bce .. ']]'
if categoryNamePrefix then
local infix = ' в '
if millenium == 2 then
infix = ' во '
end
return value .. '[[Category:' .. categoryNamePrefix .. infix .. millenium .. '-м тысячелетии' .. bce .. ']]'
else
return value
end
end
local function formatDateImpl( value, options, microformatClass, categoryPrefix, leftBracket, rightBracket, nolinks, isGenitive )
if ( not value ) then error( 'value not specified'); end
if ( not options ) then error( 'options not specified'); end
-- The calendar model used for saving the data is always the proleptic Gregorian calendar according to ISO 8601.
local timeISO8601 = string.gsub( string.gsub( tostring( value.time ), '-00%-', '-01-' ), '-00T', '-01T' )
local unixtime = parseISO8601( timeISO8601 )
if not unixtime then
return ''
end
local structure = os.date("*t", unixtime)
local precision = tonumber( value.precision )
if precision <= 6 then
return formatMillenium( structure, categoryPrefix, isGenitive )
end
if precision == 7 then
return formatCentury( structure, categoryPrefix, isGenitive )
end
if precision == 8 then
return formatDecade( structure, categoryPrefix, isGenitive )
end
if precision == 9 then
local tCopy = deepcopy( structure )
tCopy.day = nil
tCopy.month = nil
return moduleDates.formatWikiImpl( tCopy, tCopy, infoclass, categoryPrefix, leftBracket, rightBracket, nolinks )
end
-- year and month only
if precision == 10 then
local tCopy = deepcopy( structure )
tCopy.day = nil
return moduleDates.formatWikiImpl( tCopy, tCopy, infoclass, categoryPrefix, leftBracket, rightBracket, nolinks )
end
local calendarmodel = 'gregorian'
if (mw.ustring.find(value.calendarmodel, 'Q1985786', 1, true)) then
calendarmodel = 'julian'
end
if (calendarmodel == 'gregorian') then
return moduleDates.formatWikiImpl( structure, structure, microformatClass, categoryPrefix, leftBracket, rightBracket, nolinks )
else
return p.formatAsJulian( timeISO8601, infoclass, categoryPrefix, leftBracket, rightBracket, nolinks )
end
end
local function formatApproximateDateClaim( context, options, statement, unknownDateCategory )
if ( not context ) then error( 'context not specified'); end
if ( not options ) then error( 'options not specified'); end
if ( not options.entity ) then error( 'options.entity is missing'); end
if ( not statement ) then error( 'statement not specified'); end
if options.nocat then unknownDateCategory = "" end
local qNotSoonerThan = getQualifierWithDataValue( statement, 'P1319' )
local qNotLaterThan = getQualifierWithDataValue( statement, 'P1326' )
if ( qNotSoonerThan or qNotLaterThan ) then
local results = {}
if ( qNotSoonerThan ) then
local formattedDate = formatDateImpl( qNotSoonerThan.datavalue.value, {}, nil, nil, options.leftBracket, options.rightBracket, options.nolinks, true )
local value = 'не ранее ' .. context.wrapSnak( formattedDate, qNotSoonerThan.hash )
table.insert( results, context.wrapQualifier( value, 'P1319' ) )
end
if ( qNotLaterThan ) then
local formattedDate = formatDateImpl( qNotLaterThan.datavalue.value, {}, nil, nil, options.leftBracket, options.rightBracket, options.nolinks, true )
local value = 'не позднее ' .. context.wrapSnak( formattedDate, qNotLaterThan.hash )
table.insert( results, context.wrapQualifier( value, 'P1326' ) )
end
return mw.text.listToText( results, ' и ' , ' и ' ) .. unknownDateCategory .. context.formatRefs( options, statement )
end
return nil
end
function p.formatDateOfBirthClaim( context, options, statement )
local value = formatApproximateDateClaim( context, options, statement, dateCat.categoryUnknownBirthDate )
if value then
return value
end
options['conjunction'] = ' или '
options['value-module'] = 'Wikidata/date'
options['value-function'] = 'formatBirthDate'
options.i18n.somevalue = '\'\'неизвестно\'\'' .. dateCat.categoryUnknownBirthDate
local circumstances = context.getSourcingCircumstances( statement )
for _, itemId in ipairs( circumstances ) do
if itemId == 'Q5727902' then
options.isGenitive = true
break
end
end
local result = context.formatStatementDefault( context, options, statement )
local bTable = { parseClaim( statement ) }
local dTable = parseProperty ( context, options, 'P570' )
if ( bTable and not dTable ) then
local age = ageCurrent( bTable )
if ( age ) then
if ( options.suppressAge == nil or options.suppressAge == '' ) then
result = result .. ' <span style="white-space:nowrap;">(' .. age .. ' ' .. mw.language.new( 'ru' ):plural( age, 'год', 'года', 'лет') .. ')</span>'
end
if ( not options.nocat ) then
if ( age > 115 ) then
result = result .. dateCat.categoryBigCurrentAge
elseif (age >= 0) then
result = result .. dateCat.categoryBiographiesOfLivingPersons
else
result = result .. dateCat.categoryNegativeAge
end
end
end
end
return result
end
function p.formatDateOfDeathClaim( context, options, statement )
local value = formatApproximateDateClaim( context, options, statement, dateCat.categoryUnknownDeathDate )
if value then
return value
end
options['conjunction'] = ' или '
options['value-module'] = 'Wikidata/date'
options['value-function'] = 'formatDeathDate'
options.i18n.somevalue = '\'\'неизвестно\'\'' .. dateCat.categoryUnknownDeathDate
local circumstances = context.getSourcingCircumstances( statement )
for _, itemId in ipairs( circumstances ) do
if itemId == 'Q5727902' then
options.isGenitive = true
break
end
end
local result = context.formatStatementDefault( context, options, statement )
local bTable = parseProperty ( context, options, 'P569' )
local dTable = { parseClaim( statement ) }
if ( bTable and dTable ) then
local age = age( bTable, dTable )
if ( age ) then
if ( options.suppressAge == nil or options.suppressAge == '' ) then
result = result .. ' <span style="white-space:nowrap;">(' .. age .. ' ' .. mw.language.new( 'ru' ):plural( age, 'год', 'года', 'лет') .. ')</span>'
end
if ( not options.nocat and age < 0) then
result = result .. dateCat.categoryNegativeAge
end
end
-- returns category to recently deceased persons
local unixAvailable, unixDateOfDeath = pcall(function()
local r = os.time(dTable[1].structure)
if ( r ~= os.time() ) then
return r
end
error()
end)
if ( unixAvailable and os.time() - unixDateOfDeath < 31536000 and not options.nocat ) then
result = result .. dateCat.categoryRecentlyDeceased
end
end
return result
end
-- Reentry point for Wikidata Snak formatting
function p.formatBirthDate( context, options, value )
if ( not context ) then error( 'context not specified'); end
if ( not options ) then error( 'options not specified'); end
if ( not value ) then error( 'value not specified'); end
local microformatClass = nil
if options.microformat ~= '-' then
microformatClass = options.microformat or 'bday'
end
if ( options.nocat ) then
return formatDateImpl( value, options, microformatClass, nil, options.leftBracket, options.rightBracket, options.nolinks, options.isGenitive )
else
return formatDateImpl( value, options, microformatClass, 'Родившиеся', options.leftBracket, options.rightBracket, options.nolinks, options.isGenitive )
end
end
-- Reentry point for Wikidata Snak formatting
function p.formatDeathDate( context, options, value )
if ( not context ) then error( 'context not specified'); end
if ( not options ) then error( 'options not specified'); end
if ( not value ) then error( 'value not specified'); end
local microformatClass = nil
if options.microformat ~= '-' then
microformatClass = options.microformat or 'dday'
end
if ( options.nocat and options.nocat ~= '' ) then
return formatDateImpl( value, options, microformatClass, nil, options.leftBracket, options.rightBracket, options.nolinks, options.isGenitive )
else
return formatDateImpl( value, options, microformatClass, 'Умершие', options.leftBracket, options.rightBracket, options.nolinks, options.isGenitive )
end
end
-- Reentry point for Wikidata Snak formatting -- default one
function p.formatDate( context, options, value )
if ( not context ) then error( 'context not specified'); end
if ( not options ) then error( 'options not specified'); end
if ( not value ) then error( 'value not specified'); end
local microformatClass = options.microformat or nil
if ( options.nocat and options.nocat ~= '' ) then
return formatDateImpl( value, options, microformatClass, nil, options.leftBracket, options.rightBracket, options.nolinks, options.isGenitive )
else
local categoryPrefix = options.categoryPrefix or nil
return formatDateImpl( value, options, microformatClass, categoryPrefix, options.leftBracket, options.rightBracket, options.nolinks, options.isGenitive )
end
end
function p.formatDateIntervalProperty( context, options )
if ( not context ) then error( 'context not specified' ); end
if ( not options ) then error( 'options not specified' ); end
if ( not options.entity ) then error( 'options.entity missing' ); end
-- Получение нужных утверждений
local WDS = require( 'Module:WikidataSelectors' )
local fromProperty = options.property
if options.from and options.from ~= '' then
fromProperty = options.from
end
local fromClaims = WDS.load( options.entityId, fromProperty )
local toClaims = WDS.load( options.entityId, options.to )
if fromClaims == nil and toClaims == nil then
return ''
end
local formattedFromClaims = {}
if fromClaims then
for i, claim in ipairs( fromClaims ) do
local formattedStatement = context.formatStatement( options, claim )
if formattedStatement then
formattedStatement = '<span class="wikidata-claim" data-wikidata-property-id="' .. string.upper( options.property ) .. '" data-wikidata-claim-id="' .. claim.id .. '">' .. formattedStatement .. '</span>'
table.insert( formattedFromClaims, formattedStatement )
end
end
end
local formattedToClaims = {}
local toOptions = deepcopy( options )
toOptions.property = options.to
toOptions.novalue = nowLabel
if toClaims then
for i, claim in ipairs( toClaims ) do
local formattedStatement = context.formatStatement( toOptions, claim )
if formattedStatement then
formattedStatement = '<span class="wikidata-claim" data-wikidata-property-id="' .. string.upper( toOptions.property ) .. '" data-wikidata-claim-id="' .. claim.id .. '">' .. formattedStatement .. '</span>'
table.insert( formattedToClaims, formattedStatement )
end
end
end
local out = ''
local fromOut = mw.text.listToText( formattedFromClaims, options.separator, options.conjunction )
local toOut = mw.text.listToText( formattedToClaims, options.separator, options.conjunction )
if fromOut ~= '' or toOut ~= '' then
if fromOut ~= '' then
out = fromOut
else
out = '?'
end
if toOut ~= '' then
out = out .. ' — ' .. toOut
else
local withinClaims = nil
if options.within then
WDS.load( options.entityId, options.within )
end
if withinClaims == nil then
out = 'с ' .. out
else
out = out .. ' — ' .. nowLabel
end
end
end
if out ~= '' then
if options.before then
out = options.before .. out
end
if options.after then
out = out .. options.after
end
end
return out
end
local lowestBoundary = '1582-10-05T00:00:00Z'
local lastBoundary = '1918-01-31T00:00:00Z'
local boundaries = {
-- from (G) till next will be diff(G = J + diff), at current
{ lowestBoundary, 10 },
{ '1700-02-29T00:00:00Z', 11 },
{ '1800-02-29T00:00:00Z', 12 },
{ '1900-02-29T00:00:00Z', 13 },
{ lastBoundary, '' },
}
-- Передаваемое время обязано быть по Юлианскому календарю (старому стилю)
function p.formatAsJulian( julTimeISO8601, infocardClass, categoryNamePrefix, leftBracket, rightBracket, nolinks )
if 'table' == type( julTimeISO8601 ) then
if julTimeISO8601.args and julTimeISO8601.args[1] then
julTimeISO8601 = julTimeISO8601.args[1]
else
return 'unknown argument type: ' .. type( julTime ) .. ': ' .. table.tostring( julTime )
end
end
julTimeISO8601 = mw.text.trim( julTimeISO8601 )
julTimeISO8601 = string.gsub( julTimeISO8601, '^+', '' )
local julTime = parseISO8601( julTimeISO8601 )
local t = os.date( "*t", julTime )
if ( julTime < parseISO8601( lowestBoundary ) ) then
-- only julian
if string.find( julTimeISO8601, '-02-29T', 1, true ) then
t = { year = t.year, month = 2, day = 29 }
end
return moduleDates.formatWikiImpl( t, t, infocardClass, categoryNamePrefix, leftBracket, rightBracket, nolinks )
end
if ( julTimeISO8601 >= lastBoundary ) then
return "''некорректная дата (юлианский календарь не используется после 1918-01-26)''"
end
-- julian and grigorian
for i = 1, #boundaries, 1 do
local b1 = boundaries[i][1]
local b2 = boundaries[i + 1][1]
if ( b1 <= julTimeISO8601 and julTimeISO8601 < b2 ) then
local diff = boundaries[i][2]
if string.sub( julTimeISO8601, 1, 10 ) == string.sub( boundaries[i][1], 1, 10 ) then
t = { year = t.year, month = 2, day = 29 }
diff = diff - 1
end
local gregTime = os.date( "*t", julTime + diff * 24 * 60 * 60 )
return moduleDates.formatWikiImpl( t, gregTime, infocardClass, categoryNamePrefix, leftBracket, rightBracket, nolinks )
end
end
return "''ошибка в модуле Модуль:Wikidata/date''"
end
return p
12c2c34efd103d2938bd65421aa550e8c6f26da0
Модуль:Sources
828
140
322
2024-06-10T20:41:59Z
ruwiki>Stjn
0
возврат, сломало [[Википедия:Форум/Технический#Ошибка lua]]
Scribunto
text/plain
---@alias args table
---@alias frame { args: args, extensionTag: function, newChild: ( fun( args: args ): frame ) }
---@alias source { publication: source, [string]: any }
---@alias value: string | { id: string }
---@alias snak { datatype: string, snaktype: string, datavalue: { type: string, value: value } }
---@alias snaks table<string, table<number, snak>>
---@alias statement { mainsnak: snak, rank: string, qualifiers: snaks }
---@alias statements table<string, table<number, statement>>
---@alias map { name: string, ids: string[] }[]>
---@type table
local p = {}
---@type table<string, string>
local NORMATIVE_DOCUMENTS = {
Q20754888 = 'Закон Российской Федерации',
Q20754884 = 'Закон РСФСР',
Q20873831 = 'Распоряжение Президента Российской Федерации',
Q20873834 = 'Указ исполняющего обязанности Президента Российской Федерации',
Q2061228 = 'Указ Президента Российской Федерации',
}
---@type table<string, string>
local LANG_CACHE = {
Q150 = 'fr',
Q188 = 'de',
Q1321 = 'es',
Q1860 = 'en',
Q652 = 'it',
Q7737 = 'ru',
Q8798 = 'uk',
}
---@type map
local PROPERTY_MAP = {
{ name = 'sourceId', ids = { 'P248', 'P805' } },
{ name = 'lang', ids = { 'P407', 'P364' } },
{ name = 'author', ids = { 'P50', 'P2093' } },
{ name = 'part', ids = { 'P958', 'P1810' } },
{ name = 'title', ids = { 'P1476' } },
{ name = 'subtitle', ids = { 'P1680' } },
{ name = 'url', ids = { 'P953', 'P1065', 'P854', 'P973', 'P2699', 'P888' } },
{ name = 'editor', ids = { 'P98' } },
{ name = 'translator', ids = { 'P655' } },
{ name = 'publication-id', ids = { 'P1433' } },
{ name = 'edition', ids = { 'P393' } },
{ name = 'publisher', ids = { 'P123' } },
{ name = 'place', ids = { 'P291' } },
{ name = 'volume', ids = { 'P478' } },
{ name = 'issue', ids = { 'P433' } },
{ name = 'dateOfCreation', ids = { 'P571' } },
{ name = 'dateOfPublication', ids = { 'P577' } },
{ name = 'pages', ids = { 'P304' } },
{ name = 'numberOfPages', ids = { 'P1104' } },
{ name = 'tirage', ids = { 'P1092' } },
{ name = 'isbn', ids = { 'P212', 'P957' } },
{ name = 'issn', ids = { 'P236' } },
-- { name = 'accessdate', ids = { 'P813' } }, -- disable, creates duplicate references
{ name = 'docNumber', ids = { 'P1545' } },
{ name = 'type', ids = { 'P31' } },
{ name = 'arxiv', ids = { 'P818' } },
{ name = 'doi', ids = { 'P356' } },
{ name = 'pmid', ids = { 'P698' } },
}
-- table.insert( PROPERTY_MAP.url, 'P856' ) -- only as qualifier
---@type map
local PUBLICATION_PROPERTY_MAP = mw.clone( PROPERTY_MAP )
---@type string[]
local monthGen = { 'января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря' }
---@type string
local i18nDefaultLanguage = mw.language.getContentLanguage():getCode()
p.i18nDefaultLanguage = i18nDefaultLanguage
---@type string
local i18nEtAlDefault = ' et al.'
---@type table<string, string>
local i18nEtAl = {
ru = ' и др.',
uk = ' та ін.',
}
---@type table<string, string>
local i18nEditors = {
fr = '',
de = 'Hrsg.: ',
es = '',
en = '',
it = '',
ru = 'под ред. ',
uk = 'за ред. ',
}
---@type table<string, string>
local i18nTranslators = {
fr = '',
de = '',
es = '',
en = '',
it = '',
ru = 'пер. ',
uk = 'пер. ',
}
---@type table<string, string>
local i18nVolume = {
de = 'Vol.',
fr = 'Vol.',
es = 'Vol.',
en = 'Vol.',
it = 'Vol.',
ru = 'Т.',
uk = 'Т.',
}
---@type table<string, string>
local i18nIssue = {
en = 'Iss.',
ru = 'вып.',
uk = 'вип.',
}
---@type table<string, string>
local i18nPages = {
fr = 'P.',
de = 'S.',
es = 'P.',
en = 'P.',
it = 'P.',
ru = 'С.',
uk = 'С.',
}
---@type table<string, string>
local i18nNumberOfPages = {
en = 'p.',
ru = 'с.',
}
---@type table<string, string>
local i18nTirage = {
en = 'ed. size: %d',
ru = '%d экз.',
}
---@param args args
---@return source
local function getFilledArgs( args )
---@type source
local data = {}
for key, value in pairs( args ) do
if mw.text.trim( value ) ~= '' then
if key == 1 then
key = 'sourceId'
end
data[ key ] = mw.text.trim( value )
end
end
return data
end
---Returns formatted pair {Family name(s), First name(s)}
---@param fullName string
---@return table<number, string>
local function tokenizeName( fullName )
local space = '%s+' -- matches single or more spacing character
local name = "(%a[%a%-']*)%.?" -- matches single name, have to start with letter, can contain apostrophe and hyphen, may end with dot
local surname = "(%a[%a%-']*)" -- same as name, but can't end with dot
local surnamePrefixes = { 'ван', 'van', 'де', 'de' }
local nm, nm2, srn, srn2, pref
fullName = ' ' .. fullName .. ' '
fullName = mw.ustring.gsub( fullName, ' оглы ', ' ' )
fullName = mw.text.trim( fullName )
-- Surname, Name
local pattern = '^' .. surname .. ',' .. space .. name .. '$'
srn, nm = mw.ustring.match( fullName, pattern )
if srn then
return {
srn,
mw.ustring.sub( nm, 1, 1 ) .. '.'
}
end
-- Surname, Name prefix
for _, surnamePrefix in pairs( surnamePrefixes ) do
pattern = '^' .. surname .. ',' .. space .. name .. space .. '(' .. surnamePrefix .. ')' .. '$'
srn, nm, pref = mw.ustring.match( fullName, pattern )
if srn then
return {
mw.ustring.sub( pref ) .. ' ' .. srn,
mw.ustring.sub( nm, 1, 1 ) .. '.' }
end
end
-- Surname, Name Name
pattern = '^' .. surname .. ',' .. space .. name .. space .. name .. '$'
srn, nm, nm2 = mw.ustring.match( fullName, pattern )
if srn then
return {
srn,
mw.ustring.sub( nm, 1, 1 ) .. '. ' .. mw.ustring.sub( nm2, 1, 1 ) .. '.'
}
end
-- Surname Surname, Name
pattern = '^' .. surname .. space .. surname .. ',' .. space .. name .. '$'
srn, srn2, nm = mw.ustring.match( fullName, pattern )
if srn then
return {
srn .. ' ' .. srn2,
mw.ustring.sub( nm, 1, 1 ) .. '.'
}
end
-- Name Name Surname
pattern = '^' .. name .. space .. name .. space .. surname .. '$'
nm, nm2, srn = mw.ustring.match( fullName, pattern )
if srn then
return {
srn,
mw.ustring.sub( nm, 1, 1 ) .. '. ' .. mw.ustring.sub( nm2, 1, 1 ) .. '.'
}
end
-- Name Name prefix Surname
for _, surnamePrefix in pairs( surnamePrefixes ) do
pattern = '^' .. name .. space .. name .. space .. '(' .. surnamePrefix .. ')' .. space .. surname .. '$'
nm, nm2, pref, srn = mw.ustring.match( fullName, pattern )
if srn then
return {
mw.ustring.sub( pref ) .. ' ' .. srn,
mw.ustring.sub( nm, 1, 1 ) .. '. ' .. mw.ustring.sub( nm2, 1, 1 ) .. '.'
}
end
end
-- Surname, Name Name prefix
for _, surnamePrefix in pairs( surnamePrefixes ) do
pattern = '^' .. surname .. ',' .. space .. name .. space .. name .. space .. '(' .. surnamePrefix .. ')' .. '$'
srn, nm, nm2, pref = mw.ustring.match( fullName, pattern )
if srn then
return {
mw.ustring.sub( pref ) .. ' ' .. srn,
mw.ustring.sub( nm, 1, 1 ) .. '. ' .. mw.ustring.sub( nm2, 1, 1 ) .. '.'
}
end
end
-- Name{1,4} Surname
for k = 1, 4 do
pattern = '^' .. string.rep( name .. space, k ) .. surname .. '$'
---@type string[]
local matched = { mw.ustring.match( fullName, pattern ) }
if #matched ~= 0 then
for j = 1, k do
matched[ j ] = mw.ustring.sub( matched[ j ], 1, 1 )
end
return {
matched[ k + 1 ],
table.concat( matched, '. ', 1, k ) .. '.'
}
end
end
-- Surname Name{1,4}
for k = 1, 4 do
pattern = '^' .. surname .. string.rep( space .. name, k ) .. '$'
---@type string[]
local matched = { mw.ustring.match( fullName, pattern ) }
if #matched ~= 0 then
for j = 2, k + 1 do
matched[ j ] = mw.ustring.sub( matched[ j ], 1, 1 )
end
return {
matched[ 1 ],
table.concat( matched, '. ', 2, k + 1 ) .. '.'
}
end
end
return { fullName }
end
---@param fullName string | nil
---@return string | nil
local function personNameToAuthorName( fullName )
if not fullName then
return nil
end
local tokenized = tokenizeName( fullName )
if #tokenized == 1 then
return tokenized[ 1 ]
end
return tokenized[ 1 ] .. ' ' .. tokenized[ 2 ]
end
---@param fullName string | nil
---@return string | nil
local function personNameToResponsibleName( fullName )
if not fullName then
return nil
end
local tokenized = tokenizeName( fullName )
if #tokenized == 1 then
return tokenized[ 1 ]
end
return tokenized[ 2 ] .. ' ' .. tokenized[ 1 ]
end
---@alias options { separator: string, conjunction: string, format: ( fun( data: string ): string ), nolinks: boolean, preferids: boolean, short: boolean }
---@type options
local options_commas = {
separator = ', ',
conjunction = ', ',
format = function( data ) return data end,
nolinks = false,
preferids = false,
short = false,
}
---@type options
local options_commas_short = mw.clone( options_commas )
options_commas_short.short = true
---@type options
local options_commas_it_short = mw.clone( options_commas_short )
options_commas_it_short.format = function( data ) return "''" .. data .. "''" end
---@type options
local options_commas_nolinks = mw.clone( options_commas )
options_commas_nolinks.nolinks = true
---@type options
local options_citetypes = {
separator = ' ',
conjunction = ' ',
format = function( data ) return 'citetype_' .. data end,
nolinks = true ,
preferids = true,
short = false,
}
---@type options
local options_commas_authors = mw.clone( options_commas )
options_commas_authors.format = personNameToAuthorName
---@type options
local options_commas_responsible = mw.clone( options_commas )
options_commas_responsible.format = personNameToResponsibleName
---@type options
local options_ids = {
separator = '; ',
conjunction = '; ',
format = function( id ) return id end,
nolinks = true,
preferids = false,
short = false,
}
---@type options
local options_arxiv = mw.clone( options_ids )
options_arxiv.format = function( id ) return '[https://arxiv.org/abs/' .. id .. ' arXiv:' .. id .. ']' end
---@type options
local options_doi = mw.clone( options_ids )
options_doi.format = function( doi ) return '[https://dx.doi.org/' .. doi .. ' doi:' .. doi .. ']' end
---@type options
local options_issn = mw.clone( options_ids )
options_issn.format = function( issn ) return '[https://www.worldcat.org/issn/' .. issn .. ' ' .. issn .. ']' end
---@type options
local options_pmid = mw.clone( options_ids )
options_pmid.format = function( pmid ) return '[https://www.ncbi.nlm.nih.gov/pubmed/?term=' .. pmid .. ' PMID:' .. pmid .. ']' end
---@param str string | nil
---@return boolean
local function isEmpty( str )
return not str or #str == 0
end
---@param allQualifiers snaks
---@param qualifierPropertyId string
---@return string | nil
local function getSingleStringQualifierValue( allQualifiers, qualifierPropertyId )
if not allQualifiers or not allQualifiers[ qualifierPropertyId ] then
return nil
end
---@type table<number, snak>
local propertyQualifiers = allQualifiers[ qualifierPropertyId ]
for _, qualifier in pairs( propertyQualifiers ) do
if ( qualifier
and qualifier.datatype == 'string'
and qualifier.datavalue
and qualifier.datavalue.type == 'string'
and qualifier.datavalue.value ~= ''
) then
return qualifier.datavalue.value
end
end
return nil
end
---@param data table
---@param resultProperty string
---@return void
local function appendImpl_toTable( data, resultProperty )
if not data[ resultProperty ] then
data[ resultProperty ] = {}
elseif ( type( data[ resultProperty ] ) == 'string' or ( type( data[ resultProperty ] ) == 'table' and type( data[ resultProperty ].id ) == 'string' ) ) then
data[ resultProperty ] = { data[ resultProperty ] }
end
end
---@param datavalue table
---@param qualifiers snaks
---@param data table
---@param propertyName string
---@param options table
local function appendImpl( datavalue, qualifiers, data, propertyName, options )
data[ propertyName ] = data[ propertyName ] or {}
if propertyName == 'issn' then
table.insert( data[ propertyName ], datavalue.value )
elseif propertyName == 'url' or datavalue.type == 'url' then
local value = datavalue.value
if options.format then
value = options.format( value )
end
appendImpl_toTable( data, propertyName )
table.insert( data[ propertyName ], value )
elseif datavalue.type == 'string' then
local value = getSingleStringQualifierValue( qualifiers, 'P1932' )
if not value then
value = getSingleStringQualifierValue( qualifiers, 'P1810' )
end
if not value then
value = datavalue.value
if options.format then
value = options.format( value )
end
end
appendImpl_toTable(data, propertyName)
local pos = getSingleStringQualifierValue( qualifiers, 'P1545' )
if pos then
table.insert( data[ propertyName ], tonumber(pos), value )
else
table.insert( data[ propertyName ], value )
end
elseif datavalue.type == 'monolingualtext' then
local value = datavalue.value.text
if options.format then
value = options.format( value )
end
appendImpl_toTable( data, propertyName )
table.insert( data[ propertyName ], value )
elseif datavalue.type == 'quantity' then
local value = datavalue.value.amount
if ( mw.ustring.sub( value , 1, 1 ) == '+' ) then
value = mw.ustring.sub( value , 2 )
end
if options.format then
value = options.format( value )
end
appendImpl_toTable( data, propertyName )
table.insert( data[ propertyName ], value )
elseif datavalue.type == 'wikibase-entityid' then
local pos = getSingleStringQualifierValue( qualifiers, 'P1545' )
local value = datavalue.value
appendImpl_toTable(data, propertyName)
local label = getSingleStringQualifierValue( qualifiers, 'P1932' )
if not label then
label = getSingleStringQualifierValue( qualifiers, 'P1810' )
end
local toInsert = {
id = value.id,
label = label
}
if pos and tonumber( pos ) then
table.insert( data[ propertyName ], tonumber( pos ), toInsert )
else
table.insert( data[ propertyName ], toInsert )
end
elseif datavalue.type == 'time' then
local value = datavalue.value
if options.format then
value = options.format( value )
end
appendImpl_toTable( data, propertyName )
table.insert( data[ propertyName ], tostring( value.time ) )
end
end
---@param entityId string
---@param propertyId string
---@return table<number, statement>
local function getAllStatements( entityId, propertyId )
---@type boolean, table<number, statement>
local wdStatus, statements = pcall( mw.wikibase.getAllStatements, entityId, propertyId )
if wdStatus and statements then
return statements
end
return {}
end
---@param entityId string
---@param propertyId string
---@return table<number, statement>
local function getBestStatements( entityId, propertyId )
---@type boolean, table<number, statement>
local wdStatus, statements = pcall( mw.wikibase.getBestStatements, entityId, propertyId )
if wdStatus and statements then
return statements
end
return {}
end
---@param entityId string
---@param projectToCheck string?
---@return string | nil
local function getSitelink( entityId, projectToCheck )
---@type boolean, string
local wbStatus, sitelink
if projectToCheck then
wbStatus, sitelink = pcall( mw.wikibase.getSitelink, entityId, projectToCheck )
else
wbStatus, sitelink = pcall( mw.wikibase.getSitelink, entityId )
end
if not wbStatus then
return nil
end
return sitelink
end
---@param args any[]
---@return any | nil
local function coalesce( args )
for _, arg in pairs( args ) do
if not isEmpty( arg ) then return arg end
end
return nil
end
---@param value any
---@return string | nil
local function getSingle( value )
if type( value ) == 'string' then
return tostring( value )
elseif type( value ) == 'table' then
if value.id then
return tostring( value.id )
end
for _, tableValue in pairs( value ) do
return getSingle( tableValue )
end
end
return nil
end
---@param langEntityId string
---@return string | nil
local function getLangCode( langEntityId )
if not langEntityId then
return nil
end
langEntityId = getSingle( langEntityId )
if not string.match( langEntityId, '^Q%d+$' ) then
return langEntityId
end
local cached = LANG_CACHE[ langEntityId ]
if cached then
if cached == '' then
return nil
end
return cached
end
local claims = getBestStatements( langEntityId, 'P424' )
for _, claim in pairs( claims ) do
if claim
and claim.mainsnak
and claim.mainsnak.datavalue
and claim.mainsnak.datavalue.value
then
LANG_CACHE[ langEntityId ] = claim.mainsnak.datavalue.value
return claim.mainsnak.datavalue.value
end
end
LANG_CACHE[ langEntityId ] = ''
return nil
end
---@param entityId string
---@param propertyId string
---@param data source
---@param propertyName string
---@param options table?
---@return void
local function appendEntitySnaks( entityId, propertyId, data, propertyName, options )
options = options or {}
-- do not populate twice
if data[ propertyName ] and ( propertyName ~= 'author' or data[ propertyId ] ) then
return
end
local statements = getBestStatements( entityId, propertyId )
if propertyName == 'author' then
data[ propertyId ] = true
end
local lang = getLangCode( data.lang ) or i18nDefaultLanguage
if propertyId == 'P1680' then -- if there is a default language
for _, statement in pairs( statements ) do
if statement and
statement.mainsnak and
statement.mainsnak.datavalue and
statement.mainsnak.datavalue.value and
statement.mainsnak.datavalue.value.language == lang
then
--found default language string
appendImpl( statement.mainsnak.datavalue, statement.qualifiers, data, propertyName, options )
return
end
end
end
for _, statement in pairs( statements ) do
if statement and statement.mainsnak and statement.mainsnak.datavalue then
appendImpl( statement.mainsnak.datavalue, statement.qualifiers or {}, data, propertyName, options )
if propertyName == 'publication-id' and statement.qualifiers then
data[ 'publication-qualifiers' ] = statement.qualifiers
end
end
end
end
---@param claims table<number, statement>
---@param qualifierPropertyId string
---@param result table
---@param resultPropertyId string
---@param options table
---@return void
local function appendQualifiers( claims, qualifierPropertyId, result, resultPropertyId, options )
-- do not populate twice
if not claims or result[ resultPropertyId ] then
return
end
for _, claim in pairs( claims ) do
if claim.qualifiers and claim.qualifiers[ qualifierPropertyId ] then
---@type table<number, snak>
local propertyQualifiers = claim.qualifiers[ qualifierPropertyId ]
for _, qualifier in pairs( propertyQualifiers ) do
if qualifier and qualifier.datavalue then
appendImpl( qualifier.datavalue, nil, result, resultPropertyId, options )
end
end
end
end
end
---@param entityId string
---@param propertyId string
---@param value any
---@return table<number, statement>
local function findClaimsByValue( entityId, propertyId, value )
local result = {}
local claims = getAllStatements( entityId, propertyId )
for _, claim in pairs( claims ) do
if ( claim.mainsnak and claim.mainsnak.datavalue ) then
local datavalue = claim.mainsnak.datavalue
if ( datavalue.type == "string" and datavalue.value == value ) or
( datavalue.type == "wikibase-entityid" and
datavalue.value[ "entity-type" ] == "item" and
tostring( datavalue.value.id ) == value )
then
table.insert( result, claim )
end
end
end
return result
end
---@param entityId string
---@param typeEntityId string
---@return boolean
local function isInstanceOf( entityId, typeEntityId )
return findClaimsByValue( entityId, 'P31', typeEntityId )[ 1 ] ~= nil
end
---@param entityId string
---@param typeEntityIds string[]
---@return string
---@todo Rewrite
local function getFirstType( entityId, typeEntityIds )
for _, typeEntityId in pairs( typeEntityIds ) do
if isInstanceOf( entityId, typeEntityId ) then
return typeEntityId
end
end
return nil
end
---@param snaks snaks
---@param data source
---@param map map
---@return void
local function populateDataFromSnaks( snaks, data, map )
for _, row in ipairs( map ) do
local parameterName, propertyIds = row.name, row.ids
for _, propertyId in pairs( propertyIds ) do
if not data[ parameterName ] and snaks[ propertyId ] then
local options = {}
if propertyId == 'P888' then
options = { format = function( id ) return 'http://www.jstor.org/stable/' .. id end }
end
for _, snak in pairs( snaks[ propertyId ] ) do
if snak and snak.datavalue then
appendImpl( snak.datavalue, {}, data, parameterName, options )
end
end
end
end
end
end
---@param entityId string | nil
---@param data source
---@param map map
---@return void
local function populateDataFromEntity( entityId, data, map )
if not data.title then
if not isEmpty( entityId ) then
local optionsAsLinks = { format = function( text ) return { id = entityId, label = text } end }
appendEntitySnaks( entityId, 'P1476', data, 'title', optionsAsLinks )
else
appendEntitySnaks( entityId, 'P1476', data, 'title', {} )
end
appendEntitySnaks( entityId, 'P1680', data, 'subtitle', {} )
end
local bookSeriesStatements = getBestStatements( entityId, 'P361' )
for _, statement in pairs( bookSeriesStatements ) do
if statement and
statement.mainsnak and
statement.mainsnak.datavalue and
statement.mainsnak.datavalue.value and
statement.mainsnak.datavalue.value.id
then
local possibleBookSeriesEntityId = statement.mainsnak.datavalue.value.id
if isInstanceOf( possibleBookSeriesEntityId, 'Q277759' ) then
appendImpl_toTable( data, 'bookSeries' )
table.insert( data.bookSeries, { id = possibleBookSeriesEntityId } )
appendQualifiers( { statement }, 'P478', data, 'bookSeriesVolume', {} )
appendQualifiers( { statement }, 'P433', data, 'bookSeriesIssue', {} )
end
end
end
for _, row in ipairs( map ) do
local parameterName, propertyIds = row.name, row.ids
for _, propertyId in pairs( propertyIds ) do
local options = {}
if propertyId == 'P888' then
options = { format = function( id ) return 'http://www.jstor.org/stable/' .. id end }
end
appendEntitySnaks( entityId, propertyId, data, parameterName, options )
end
end
end
---@param data source
---@return void
local function expandPublication( data )
if not data[ 'publication-id' ] then
return
end
local publicationId = getSingle( data[ 'publication-id' ] )
data.publication = {}
for key, value in pairs( data ) do
if not string.match( key, '^publication-' ) then
data.publication[ key ] = value
end
end
data.publication.sourceId = publicationId
data.publication.title = data[ 'publication-title' ]
data.publication.subtitle = data[ 'publication-subtitle' ]
if data[ 'publication-qualifiers' ] then
populateDataFromSnaks( data[ 'publication-qualifiers' ], data.publication, PUBLICATION_PROPERTY_MAP )
end
populateDataFromEntity( publicationId, data.publication, PUBLICATION_PROPERTY_MAP )
if type( data.publication.title ) == 'table' and data.publication.title[ 1 ] then
data.publication.title = data.publication.title[ 1 ]
end
if type( data.publication.subtitle ) == 'table' and data.publication.subtitle[ 1 ] then
data.publication.subtitle = data.publication.subtitle[ 1 ]
end
for key, value in pairs( data.publication ) do
if key ~= 'sourceId' and key ~= 'title' and key ~= 'subtitle' and key ~= 'url' and not data[ key ] then
data[ key ] = value
end
end
end
---@param data source
---@return void
local function expandBookSeries( data )
local bookSeries = data.bookSeries
if not bookSeries then
return
end
-- use only first one
if type( bookSeries ) == 'table' and bookSeries[ 1 ] and bookSeries[ 1 ].id then
data.bookSeries = bookSeries[ 1 ]
bookSeries = data.bookSeries
end
if not bookSeries or not bookSeries.id then
return
end
appendEntitySnaks( bookSeries.id, 'P123', data, 'publisher', {} )
appendEntitySnaks( bookSeries.id, 'P291', data, 'place', {} )
appendEntitySnaks( bookSeries.id, 'P236', data, 'issn', {} )
end
---@param entityId string
---@return string | nil
local function getNormativeTitle( entityId )
local possibleTypeIds = {}
for typeId, _ in pairs( NORMATIVE_DOCUMENTS ) do
table.insert( possibleTypeIds, typeId )
end
local foundTypeId = getFirstType( entityId, possibleTypeIds )
if foundTypeId then
return NORMATIVE_DOCUMENTS[ foundTypeId ]
end
return nil
end
---@param urls table<number, string> | string
---@param text string
---@return string
local function wrapInUrl( urls, text )
local url = getSingle( urls )
if string.sub( url, 1, 1 ) == ':' then
return '[[' .. url .. '|' .. text .. ']]'
else
return '[' .. url .. ' ' .. text .. ']'
end
end
---@param entityId string
---@param lang string
---@return string
local function getElementLink( entityId, lang )
local sitelink = getSitelink( entityId, nil )
if sitelink then
return ':' .. sitelink
end
if lang ~= 'mul' then
-- link to entity in source language
sitelink = getSitelink( entityId, lang .. 'wiki' )
if sitelink then
return ':' .. lang .. ':' .. sitelink
end
end
return ':d:' .. entityId
end
---@param entityId string
---@param lang string
---@return string
local function getLabel( entityId, lang )
local wbStatus, label = pcall( mw.wikibase.getLabelByLang, entityId, lang )
if not wbStatus then
return ''
end
if label and label ~= '' then
return label
end
wbStatus, label = pcall( mw.wikibase.getLabel, entityId )
if not wbStatus then
return ''
end
return label or ''
end
---@param lang string
---@param entityId string
---@param customTitle string
---@param options table
local function renderLink( lang, entityId, customTitle, options )
if not entityId then
error( 'entityId is not specified' )
end
if type( entityId ) ~= 'string' then
error( 'entityId is not string, but ' .. type( entityId ) )
end
if type( customTitle or '' ) ~= 'string' then
error( 'customTitle is not string, but ' .. type( customTitle ) )
end
local title = customTitle
-- ISO 4
if isEmpty( title ) then
local propertyStatements = getBestStatements( entityId, 'P1160' )
for _, claim in pairs( propertyStatements ) do
if ( claim
and claim.mainsnak
and claim.mainsnak.datavalue
and claim.mainsnak.datavalue.value
and claim.mainsnak.datavalue.value.language == lang
) then
title = claim.mainsnak.datavalue.value.text
-- mw.log( 'Got title of ' .. entityId .. ' from ISO 4 claim: «' .. title .. '»' )
break
end
end
end
-- official name P1448
-- short name P1813
if isEmpty( title ) and options.short then
local propertyStatements = getBestStatements( entityId, 'P1813' )
for _, claim in pairs( propertyStatements ) do
if ( claim
and claim.mainsnak
and claim.mainsnak.datavalue
and claim.mainsnak.datavalue.value
and claim.mainsnak.datavalue.value.language == lang
) then
title = claim.mainsnak.datavalue.value.text
-- mw.log( 'Got title of ' .. entityId .. ' from short name claim: «' .. title .. '» (' .. lang .. ')' )
break
end
end
end
-- person name P1559
-- labels
if isEmpty( title ) then
title = getLabel( entityId, lang )
-- mw.log( 'Got title of ' .. entityId .. ' from label: «' .. title .. '» (' .. lang .. ')' )
end
local actualText = title or '\'\'(untranslated)\'\''
local link = getElementLink( entityId, lang )
return wrapInUrl( link, actualText )
end
---@param lang string
---@param value value
---@param options options
---@return string
local function asString( lang, value, options )
if type( value ) == 'string' then
return options.format( value )
end
if type( value ) ~= 'table' then
return options.format( '(unknown type)' )
end
if value.id then
-- this is link
if type( value.label or '' ) ~= 'string' then
mw.logObject( value, 'error value' )
error( 'label of table value is not string but ' .. type( value.label ) )
end
local title
if options.preferids then
title = value.id
elseif options.nolinks then
title = value.label or getLabel( value.id, lang )
else
title = renderLink( lang, value.id, value.label, options )
end
if title == '' then
title = "''(untranslated title)''"
end
return options.format( title )
end
local resultList = {}
for _, tableValue in pairs( value ) do
table.insert( resultList, asString( lang, tableValue, options ) )
end
return mw.text.listToText( resultList, options.separator, options.conjunction )
end
---@param entityId string
---@param data source
---@return source
local function populateSourceDataImpl( entityId, data, map )
local wsLink = getSitelink( entityId, 'ruwikisource' )
if wsLink and not mw.ustring.gmatch( wsLink, 'Категория:' ) then
data.url = ":ru:s:" .. wsLink
end
populateDataFromEntity( entityId, data, map )
local normativeTitle = getNormativeTitle( entityId )
if normativeTitle then
local y, m, d = mw.ustring.match( getSingle( data.dateOfCreation ) , "(%-?%d+)%-(%d+)%-(%d+)T" )
y, m, d = tonumber( y ),tonumber( m ), tonumber( d )
local title = asString( 'ru', data.title, options_commas_nolinks )
local docNumber = getSingle( data.docNumber )
data.title = {
normativeTitle ..
" от " .. tostring( d ) .. " " .. monthGen[ m ] .. " " .. tostring( y ) .. " г." ..
( docNumber and ( " № " .. docNumber ) or '' ) ..
' «' .. title.. '»'
}
end
if not data.title then
local lang = getLangCode( data.lang ) or i18nDefaultLanguage
local label = getLabel( entityId, lang )
if label ~= '' then
data.title = { label }
end
end
return data
end
---@param entityId string
---@param propertyId string
---@param data source
---@return void
local function expandSpecialsQualifiers( entityId, propertyId, data )
local statements = getBestStatements( entityId, propertyId )
for _, statement in pairs( statements ) do
populateDataFromSnaks( statement.qualifiers or {}, data, PROPERTY_MAP )
end
end
---Expand special types of references when additional data could be found in OTHER entity properties
---@param data source
---@return void
local function expandSpecials( data )
if not data.entityId then
return
end
if data.sourceId == 'Q36578' then
-- Gemeinsame Normdatei -- specified by P227
appendEntitySnaks( data.entityId, 'P227', data, 'part', { format = function(gnd ) return 'Record #' .. gnd; end } )
appendEntitySnaks( data.entityId, 'P227', data, 'url', { format = function(gnd ) return 'http://d-nb.info/gnd/' .. gnd .. '/'; end } )
data.year = '2012—2016'
expandSpecialsQualifiers( data.entityId, 'P227', data )
elseif data.sourceId == 'Q15222191' then
-- BNF -- specified by P268
appendEntitySnaks( data.entityId, 'P268', data, 'part', { format = function(id ) return 'Record #' .. id; end } )
appendEntitySnaks( data.entityId, 'P268', data, 'url', { format = function(id ) return 'http://catalogue.bnf.fr/ark:/12148/cb' .. id; end } )
expandSpecialsQualifiers( data.entityId, 'P268', data )
elseif data.sourceId == 'Q54919' then
-- VIAF -- specified by P214
appendEntitySnaks( data.entityId, 'P214', data, 'part', { format = function(id ) return 'Record #' .. id; end } )
appendEntitySnaks( data.entityId, 'P214', data, 'url', { format = function(id ) return 'https://viaf.org/viaf/' .. id; end } )
expandSpecialsQualifiers( data.entityId, 'P214', data )
else
-- generic property search
for _, sourceClaim in pairs( getBestStatements( data.sourceId, 'P1687' ) ) do
if sourceClaim.mainsnak.snaktype == 'value' then
local sourcePropertyId = sourceClaim.mainsnak.datavalue.value.id
for _, sourcePropertyClaim in pairs( getBestStatements( sourcePropertyId, 'P1630' ) ) do
if sourcePropertyClaim.mainsnak.snaktype == 'value' then
appendEntitySnaks( data.entityId, sourcePropertyId, data, 'url', {
format = function( id )
return mw.ustring.gsub( mw.ustring.gsub( sourcePropertyClaim.mainsnak.datavalue.value, '$1', id ), ' ', '%%20' )
end
} )
expandSpecialsQualifiers( data.entityId, sourcePropertyId, data )
break
end
end
end
end
end
-- do we have appropriate record in P1433 ?
local claims = findClaimsByValue( currentEntityId, 'P1343', data.sourceId )
if claims and #claims ~= 0 then
for _, claim in pairs( claims ) do
populateDataFromSnaks( claim.qualifiers, data, PROPERTY_MAP )
populateDataFromEntity( data.sourceId, data, PROPERTY_MAP )
end
end
end
---@param text string
---@param tip string
---@return string
local function toTextWithTip( text, tip )
return '<span title="' .. tip .. '" style="border-bottom: 1px dotted; cursor: help; white-space: nowrap">' .. text .. '</span>'
end
---@param lang string
---@param placeId string
---@return string
local function getPlaceName( placeId, lang )
-- ГОСТ Р 7.0.12—2011
if lang == 'ru' then
if placeId == 'Q649' then return toTextWithTip( 'М.', 'Москва' ); end
if placeId == 'Q656' then return toTextWithTip( 'СПб.', 'Санкт-Петербург' ); end
if placeId == 'Q891' then return toTextWithTip( 'Н. Новгород', 'Нижний Новгород' ); end
if placeId == 'Q908' then return toTextWithTip( 'Ростов н/Д.', 'Ростов-на-Дону' ); end
end
return nil
end
---@param data source
---@param lang string
---@return void
local function preprocessPlace( data, lang )
if not data.place then
return
end
---@type table<number, string>
local newPlace = {}
for index, place in pairs( data.place ) do
if place.id then
local newPlaceStr = getPlaceName( place.id, lang )
if newPlaceStr then
newPlace[ index ] = newPlaceStr
else
newPlace[ index ] = getLabel( place.id, lang )
end
else
newPlace[ index ] = place
end
end
data.place = newPlace
end
---@param entityId string
---@param lang string
---@param providedLabel string | nil
---@param options options
---@return string
local function getPersonNameAsLabel( entityId, lang, providedLabel, options )
-- would custom label provided we don't need to check entity at all
if not isEmpty( providedLabel ) then
return options.format( providedLabel )
end
if lang == 'mul' then
lang = i18nDefaultLanguage
end
---@type string | nil
local personName = getLabel( entityId, lang )
if isEmpty( personName ) then
return '\'\'(not translated to ' .. lang .. ')\'\''
end
if not isInstanceOf( entityId, 'Q5' ) then
return personName
end
return options.format( personName )
end
---@param entityId string
---@param lang string
---@param customLabel string | nil
---@param options options
---@return string
local function getPersonNameAsWikitext( entityId, lang, customLabel, options )
local personName = getPersonNameAsLabel( entityId, lang, customLabel, options )
local link = getElementLink( entityId, lang )
return wrapInUrl( link, personName )
end
---@param value value
---@param lang string
---@param options options
---@return string
local function getPeopleAsWikitext( value, lang, options )
if type( value ) == 'string' then
return options.format( value )
elseif type( value ) == 'table' then
if value.id then
-- this is link
if options.preferids then
return tostring( value.id )
else
if options.nolinks then
return getPersonNameAsLabel( value.id, lang, value.label, options )
else
return getPersonNameAsWikitext( value.id, lang, value.label, options )
end
end
end
local maxAuthors = 10 -- need some restrictions, as some publications have enormous amount of authors (e.g. 115 authors of Q68951544)
local resultList = {}
for _, tableValue in pairs( value ) do
local nextWikitext = getPeopleAsWikitext( tableValue, lang, options )
if not isEmpty( nextWikitext ) then
table.insert( resultList, nextWikitext )
if #resultList == maxAuthors + 1 then
-- keep one more to indicate that there are too many
break
end
end
end
local resultWikitext = ''
for i, wikitext in pairs( resultList ) do
if i == maxAuthors + 1 then
resultWikitext = resultWikitext .. ( i18nEtAl[ lang ] or i18nEtAlDefault )
break
end
if i ~= 1 then
resultWikitext = resultWikitext .. ', '
end
resultWikitext = resultWikitext .. wikitext
end
return resultWikitext
end
return '' -- options.format( '(unknown type)' )
end
---@param lang string
---@param data source
---@return string
local function generateAuthorLinks( lang, data )
local result = ''
if data.author then
result = getPeopleAsWikitext( data.author, lang, options_commas_authors )
result = '<i class="wef_low_priority_links">' .. result .. '</i> '
end
return result
end
---@param lang string
---@param data source
---@param conjunction string
---@param propertyName string
---@param urlPropertyName string?
---@return string
local function appendProperty( lang, data, conjunction, propertyName, urlPropertyName )
if not data[ propertyName ] then
return ''
end
local out
if urlPropertyName and data[ urlPropertyName ] then
out = wrapInUrl( data[ urlPropertyName ], asString( lang, data[ propertyName ], options_commas_nolinks ) )
else
out = asString( lang, data[ propertyName ], options_commas )
end
if not out or out == '' then
return ''
end
return conjunction .. out
end
---@param lang string
---@param data source
---@return string
local function appendTitle( lang, data )
local conjunction = ''
local result = ''
if data.part then
result = result .. appendProperty( lang, data, '', 'part', 'parturl' )
conjunction = ' // '
end
return result .. appendProperty( lang, data, conjunction, 'title', 'url' )
end
---@param lang string
---@return string
local function appendLanguage( lang )
if lang == i18nDefaultLanguage then
return ''
end
---@type { getRefHtml: ( fun( lang: string ): string ), list_ref: ( fun( frame: frame ): string ) }
local langs = require( 'Module:Languages' )
return langs.list_ref( p.currentFrame:newChild{ args = { lang } } )
end
---@param lang string
---@param data source
---@return string
local function appendSubtitle( lang, data )
return appendProperty( lang, data, ': ', 'subtitle', nil )
end
---@param lang string
---@param data source
---@return string
local function appendOriginalTitle( lang, data )
return appendProperty( lang, data, ' = ', 'originaltitle', nil )
end
---@param lang string
---@param data source
---@return string
local function appendPublication( lang, data )
if not data.publication then
return ''
end
local result = ' // ' .. asString( lang, data.publication.title, options_commas_it_short )
if data.publication.subtitle and data.publication.subtitle ~= '' then
result = result .. ': ' .. asString( lang, data.publication.subtitle, options_commas_it_short )
end
return result
end
---@param lang string
---@param data source
---@return string
local function appendEditor( lang, data )
if not data.editor and not data.translator then
return ''
end
local result = ' / '
if data.editor then
local prefix = i18nEditors[ lang ] or i18nEditors[ i18nDefaultLanguage ]
result = result .. prefix .. getPeopleAsWikitext( data.editor, lang, options_commas_responsible )
if data.translator then
result = result .. ', '
end
end
if data.translator then
local prefix = i18nTranslators[ lang ] or i18nTranslators[ i18nDefaultLanguage ]
result = result .. prefix .. getPeopleAsWikitext( data.translator, lang, options_commas_responsible )
end
return result
end
---@param lang string
---@param data source
local function appendEdition( lang, data )
return appendProperty( lang, data, ' — ', 'edition', nil )
end
---@param lang string
---@param data source
---@return string
local function appendPublicationData( lang, data )
if not data.place and not data.publisher and not data.year then
return ''
end
local result = ' — '
if data.place then
result = result .. asString( lang, data.place, options_commas_short )
if data.publisher or data.year then
result = result .. ': '
end
end
if data.publisher then
result = result .. asString( lang, data.publisher, options_commas_short )
if data.year then
result = result .. ', '
end
end
if data.year then
result = result .. asString( lang, data.year, options_commas )
end
result = result .. '.'
return result
end
---@param lang string
---@param data source
---@return string
local function appendVolumeAndIssue( lang, data )
if not data.volume and not data.issue then
return ''
end
local result = ' — '
local letter_vol = i18nVolume[ lang ] or i18nVolume[ i18nDefaultLanguage ]
local letter_iss = i18nIssue[ lang ] or i18nIssue[ i18nDefaultLanguage ]
if data.volume then
result = result .. appendProperty( lang, data, letter_vol .. ' ', 'volume', nil )
result = result ..appendProperty( lang, data, ', ' .. letter_iss .. ' ', 'issue', nil )
else
result = result .. appendProperty( lang, data, letter_iss .. ' ', 'issue', nil )
end
result = result .. '.'
return result
end
---@param lang string
---@param data source
---@return string
local function appendPages( lang, data )
if not data.pages then
return ''
end
local letter = i18nPages[ lang ] or i18nPages[ i18nDefaultLanguage ]
local strPages = asString( lang, data.pages, options_commas )
strPages = mw.ustring.gsub( strPages, '[-—]', '—' )
return ' — ' .. letter .. ' ' .. strPages .. '.'
end
---@param lang string
---@param data source
---@return string
local function appendNumberOfPages( lang, data )
if not data.numberOfPages then
return ''
end
local letter = i18nNumberOfPages[ lang ] or i18nNumberOfPages[ i18nDefaultLanguage ]
return appendProperty( lang, data, ' — ', 'numberOfPages', nil ) .. ' ' .. letter
end
---@param lang string
---@param data source
---@return string
local function appendBookSeries( lang, data )
if not data.bookSeries then
return ''
end
local result = appendProperty( lang, data, ' — (', 'bookSeries', nil )
if data.bookSeriesVolume or data.bookSeriesIssue then
result = result .. '; '
local letter_vol = i18nVolume[ lang ] or i18nVolume[ i18nDefaultLanguage ]
local letter_iss = i18nIssue[ lang ] or i18nIssue[ i18nDefaultLanguage ]
if data.bookSeriesVolume then
result = result .. appendProperty( lang, data, letter_vol .. ' ', 'bookSeriesVolume', nil )
result = result .. appendProperty( lang, data, ', ' .. letter_iss .. ' ', 'bookSeriesIssue', nil )
else
result = result .. appendProperty( lang, data, letter_iss .. ' ', 'bookSeriesIssue', nil )
end
end
result = result .. ')'
return result
end
---@param lang string
---@param data source
---@return string
local function appendTirage( lang, data )
if not data.tirage then
return ''
end
local tirageTemplate = i18nTirage[ lang ] or i18nTirage[ i18nDefaultLanguage ]
---@type options
local optionsTirage = {
separator = '; ',
conjunction = '; ',
format = function( _data ) return tostring( mw.ustring.format( tirageTemplate, _data ) ) end,
short = false,
nolinks = false,
preferids = false,
}
return ' — ' .. asString( lang, data.tirage, optionsTirage )
end
---@param lang string
---@param value string | nil
---@param options options
---@param prefix string?
---@return string
local function appendIdentifier( lang, value, options, prefix )
if not value then
return ''
end
return ' — ' .. ( prefix or '' ) .. asString( lang, value, options )
end
---@param result string
---@param lang string
---@param data source
---@return string
local function wrapSourceId( result, lang, data )
if not data.sourceId then
return result
end
local citeType = data.type and asString( lang, data.type, options_citetypes ) or 'citetype_unknown'
return '<span class="wikidata_cite ' .. citeType .. '" data-entity-id="' .. data.sourceId .. '">' .. result .. '</span>'
end
---@param data source
---@return string
local function appendAccessDate( data )
if not data.accessdate then
return ''
end
local date = getSingle( data.accessdate )
local pattern = "(%-?%d+)%-(%d+)%-(%d+)T"
local y, m, d = mw.ustring.match( date, pattern )
y, m, d = tonumber( y ), tonumber( m ), tonumber( d )
local date_str = ( d > 0 and ' ' .. tostring( d ) or '' )
.. ( m > 0 and ' ' .. monthGen[ m ] or '' )
.. ( y > 0 and ' ' .. tostring( y ) or '' )
return " <small>Проверено" .. date_str .. ".</small>"
end
---@param data source
---@param lang string
---@return void
local function populateUrl( data, lang )
if data.sourceId and not data.url then
local sitelink = getSitelink( data.sourceId, lang .. 'wikisource' )
if sitelink then
data.url = ':' .. lang .. ':s:' .. sitelink
end
end
end
---@param data source
---@return void
local function populateYear( data )
if not data.year and data.dateOfPublication then
local date = getSingle( data.dateOfPublication )
data.year = mw.ustring.sub( date, 2, 5 )
end
if not data.year and data.dateOfCreation then
local date = getSingle( data.dateOfCreation )
data.year = mw.ustring.sub( date, 2, 5 )
end
end
---@param data source
---@return void
local function populateTitle( data )
data.title = data.title or getSingle( data.url )
end
---@param data source
---@return string
local function renderSource( data )
local lang = getLangCode( data.lang ) or i18nDefaultLanguage
preprocessPlace( data, lang )
populateUrl( data, lang )
populateTitle( data )
if not data.title then
return ''
end
populateYear( data )
local result = generateAuthorLinks( lang, data )
result = result .. appendTitle( lang, data )
result = result .. appendLanguage( lang )
result = result .. appendSubtitle( lang, data )
result = result .. appendOriginalTitle( lang, data )
result = result .. appendPublication( lang, data )
result = result .. '<span class="wef_low_priority_links">'
result = result .. appendEditor( lang, data ) -- Might take current editor instead of actual. Use with caution
result = result .. appendEdition( lang, data )
result = result .. appendPublicationData( lang, data )
result = result .. appendVolumeAndIssue( lang, data )
result = result .. appendPages( lang, data )
result = result .. appendNumberOfPages( lang, data )
result = result .. appendBookSeries( lang, data )
result = result .. appendTirage( lang, data )
result = result .. appendIdentifier( lang, data.isbn, options_commas, 'ISBN ' )
result = result .. appendIdentifier( lang, data.issn, options_issn, 'ISSN ' )
result = result .. appendIdentifier( lang, data.doi, options_doi, nil )
result = result .. appendIdentifier( lang, data.pmid, options_pmid, nil )
result = result .. appendIdentifier( lang, data.arxiv, options_arxiv, nil )
result = result .. appendAccessDate( data )
result = result .. '</span>'
return wrapSourceId( result, lang, data )
end
---@param data source Данные в простом формате, согласованном с модулями формирования библиографического описания
---@param snaks snaks
---@return string | nil
local function renderReferenceImpl( data, snaks )
-- не показывать источники с "импортировано из"
if snaks.P143 then
return nil
end
-- забрать данные из reference
populateDataFromSnaks( snaks or {}, data, PROPERTY_MAP )
data.sourceId = getSingle( data.sourceId )
populateDataFromEntity( data.sourceId, data, PROPERTY_MAP )
expandSpecials( data )
populateSourceDataImpl( data.sourceId, data, PROPERTY_MAP )
expandPublication( data )
expandBookSeries( data )
if next( data ) == nil then
return nil
end
local rendered = renderSource( data )
if mw.ustring.len( rendered ) == 0 then
return nil
end
if data.ref then
local anchorValue = 'CITEREF' .. data.ref .. ( coalesce( { data[ 'ref-year' ], data.year } ) or '' )
rendered = '<span class="citation" id="' .. mw.uri.anchorEncode( anchorValue ) .. '">' .. rendered .. '</span>'
end
return rendered
end
---@param frame frame
---@param currentEntityId string | { id: string }
---@param reference table{ snaks: snaks }
---@return string | nil
function p.renderSource( frame, currentEntityId, reference )
reference = reference or { snaks = {} }
p.currentFrame = frame
local data = getFilledArgs( frame.args or {} )
populateDataFromSnaks( reference.snaks, data, PROPERTY_MAP )
data.sourceId = getSingle( data.sourceId )
if not currentEntityId then
data.entityId = mw.wikibase.getEntityIdForCurrentPage()
elseif type( currentEntityId ) == 'string' then
data.entityId = currentEntityId
elseif type( currentEntityId ) == 'table' and currentEntityId.id then
data.entityId = currentEntityId.id
end
---@type string
local rendered = renderReferenceImpl( data, reference.snaks or {} )
if not rendered then
return ''
end
return rendered
end
---@param frame frame
---@param currentEntityId string
---@param reference table
---@return string
function p.renderReference( frame, currentEntityId, reference )
local rendered = p.renderSource( frame, currentEntityId, reference )
if not rendered or rendered == '' then
return ''
end
-- Про выбор алгоритма хеширования см. [[Модуль:Hash]]. Знак подчёркивания в начале позволяет
-- исключить ошибку, когда имя сноски — чисто числовое значение, каковыми иногда бывают хеши.
return frame:extensionTag( 'ref', rendered, { name = '_' .. mw.hash.hashValue( 'fnv164', rendered ) } ) .. '[[Category:Википедия:Статьи с источниками из Викиданных]]'
end
---@param frame frame
---@return string | nil
function p.testPersonNameToAuthorName( frame )
return personNameToAuthorName( frame.args[ 1 ] )
end
---@param frame frame
---@return string | nil
function p.testPersonNameToResponsibleName( frame )
return personNameToResponsibleName( frame.args[ 1 ] )
end
return p
752a204827a41ecd6cf518bdb22da12718bca2ec
Шаблон:Заглавная/styles.css
10
8
18
2024-06-13T19:33:39Z
ruwiki>Stjn
0
fix
sanitized-css
text/css
/*
Новое оформление [[Заглавная страница]]
Главный референс:
https://design.wikimedia.org/style-guide/
https://github.com/wikimedia/wikimedia-ui-base/blob/master/wikimedia-ui-base.less
Не удаляйте код до завершения работы
*/
/* Стандартные заголовки */
.main-header.main-header.main-header {
border-bottom-color: transparent;
margin-bottom: 0.25em;
margin-top: 0;
padding-bottom: 0;
padding-top: 0;
}
body.skin-minerva .main-block h1,
body.skin-minerva .main-block h2 {
/* хак для Минервы в связи с [[mw:Heading HTML changes]] */
display: block;
}
body.skin-timeless .main-header.main-header.main-header {
border-bottom-color: transparent;
}
/* Списки без оформления */
.main-plainlist ul {
list-style: none;
margin: 0;
padding: 0;
}
.main-plainlist li {
margin-bottom: 0;
}
/* Убираем нумерацию заголовков, создаваемую опцией «Автоматически нумеровать заголовки»
на [[Служебная:Настройки#mw-prefsection-rendering]] */
.main-block .mw-headline-number {
display: none;
}
/* Скопировано из [[:w:Template:Screen reader-only/styles.css]] */
.main-block .sr-only {
border: 0;
clip: rect(0, 0, 0, 0); /* Removed from CSS specification */
/* clip-path is the replacement for clip, but very few browsers support it. */
clip-path: polygon(0px 0px, 0px 0px, 0px 0px);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
white-space: nowrap;
}
/*
Планшеты
*/
@media (min-width: 720px) {
.main-wikimedia {
padding-left: 1rem;
padding-right: 1rem;
}
}
/*
Стационарные компьютеры
*/
@media (min-width: 1000px) {
.main-wrapper {
display: flex;
gap: 1.5rem;
/* Fixes https://phabricator.wikimedia.org/F54943102 */
flex-wrap: wrap;
}
.main-wrapper-column {
flex: 1;
}
.main-wikimedia {
padding-left: 1.5rem;
padding-right: 1.5rem;
}
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
22963811044f787be151a02e4e09cbdc96d990d3
Модуль:Message box/ombox.css
828
68
108
2024-06-21T16:47:35Z
ruwiki>Putnik
0
исправление цвета рамки
sanitized-css
text/css
/* Скопировано из [[:en:Module:Message box/ombox.css]] */
.ombox {
margin: 4px 0;
border-collapse: collapse;
border: 1px solid var(--border-color-base, #a2a9b1); /* Default "notice" gray */
background-color: var(--background-color-neutral-subtle, #f8f9fa);
box-sizing: border-box;
}
/* For the "small=yes" option. */
.ombox.mbox-small {
font-size: 88%;
line-height: 1.25em;
}
.ombox-speedy {
border: 2px solid var(--border-color-error, #b32424); /* Red */
background-color: var(--background-color-error-subtle, #fee7e6); /* Pink */
}
.ombox-delete {
border: 2px solid var(--background-color-error--active, #b32424); /* Red */
}
.ombox-content {
border: 1px solid #f28500; /* Orange */
}
.ombox-style {
border: 1px solid #fc3; /* Yellow */
}
.ombox-move {
border: 1px solid #9932cc; /* Purple */
}
.ombox-protection {
border: 2px solid var(--border-color-base, #a2a9b1); /* Gray-gold */
}
.ombox .mbox-text {
border: none;
/* @noflip */
padding: 0.25em 0.9em;
width: 100%;
}
.ombox .mbox-image {
border: none;
/* @noflip */
padding: 2px 0 2px 0.9em;
text-align: center;
}
.ombox .mbox-imageright {
border: none;
/* @noflip */
padding: 2px 0.9em 2px 0;
text-align: center;
}
/* An empty narrow cell */
.ombox .mbox-empty-cell {
border: none;
padding: 0;
width: 1px;
}
.ombox .mbox-invalid-type {
text-align: center;
}
/* Хак, TODO: посмотреть, как оно на самом деле работает */
.ombox .mbox-textsmall-div {
font-size: 90%;
}
@media (min-width: 720px) {
.ombox {
margin: 4px 10%;
}
.ombox.mbox-small {
/* @noflip */
clear: right;
/* @noflip */
float: right;
/* @noflip */
margin: 4px 0 4px 1em;
width: 238px;
}
/* Стили нотификаций для ноутбуков */
@media (max-width: 1366px) {
.ombox {
margin-left: 6%;
margin-right: 6%;
}
}
}
/* [[Категория:Модули:Подстраницы CSS]] */
6627874170f6674674bfa5796b2f7dfb6698cd81
Шаблон:Doc/begin
10
172
386
2024-06-30T22:14:58Z
ruwiki>Putnik
0
[[ВП:×|отмена]] правки 138443392 участника [[Special:Contribs/Putnik|Putnik]] ([[UT:Putnik|обс.]])
wikitext
text/x-wiki
<includeonly><templatestyles src="Шаблон:Doc/styles.css" />
<div class="ts-doc-doc" id="doc">
<div class="ts-doc-header" id="Документация">
<div class="ts-doc-heading">Документация</div>
{{#if: {{{inline|}}} || {{Действия для страницы|lc={{{1}}}|nowatch=yes}} }}
</div>
<div class="ts-doc-content"></includeonly><noinclude>
{{doc}}
</noinclude>
c753f0a9f65d86707cdffaf93fb49c2c52daf92b
Модуль:Message box/configuration
828
67
106
2024-07-05T22:32:41Z
ruwiki>Putnik
0
временное исправление шаблонов обсуждений через .notheme
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Message box configuration --
-- --
-- This module contains configuration data for [[Module:Message box]]. --
--------------------------------------------------------------------------------
return {
ambox = {
types = {
speedy = {
class = 'ambox-speedy',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'ambox-delete',
image = 'Stop hand nuvola.svg'
},
content = {
class = 'ambox-content',
image = 'Emblem-important.svg'
},
style = {
class = 'ambox-style',
image = 'Broom_icon.svg'
},
move = {
class = 'ambox-move',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'ambox-protection',
image = 'Padlock-silver-medium.svg'
},
notice = {
class = 'ambox-notice',
image = 'Information.svg'
},
good = {
class = 'ambox-good',
image = 'Green star boxed.svg'
},
serious = {
class = 'ambox-serious',
image = 'Stop hand nuvola.svg'
},
merge = {
class = 'ambox-merge',
image = 'Merge-split-transwiki default.svg'
},
discussion = {
class = 'ambox-discussion',
image = 'Nuvola apps ksirc.png'
}
},
default = 'notice',
allowBlankParams = {'talk', 'sect', 'date', 'issue', 'fix', 'subst', 'hidden', 'image'},
allowSmall = true,
smallParam = 'left',
smallClass = 'mbox-small-left',
substCheck = true,
classes = {'metadata', 'ambox'},
imageEmptyCell = true,
imageCheckBlank = true,
imageSmallSize = '20x20px',
imageCellDiv = true,
useCollapsibleTextFields = true,
imageRightNone = true,
sectionDefault = 'статья',
allowMainspaceCategories = true,
templateCategory = 'Шаблоны:Шаблоны-сообщения для статей',
templateCategoryRequireName = true,
templateErrorCategory = 'Шаблоны:Шаблоны-сообщения для статей с пропущенными параметрами',
templateErrorParamsToCheck = {'issue', 'fix'},
removalNotice = '[[Help:Maintenance template removal|Learn how and when to remove this template message]]',
templatestyles = 'Module:Message box/ambox.css',
},
cmbox = {
types = {
speedy = {
class = 'cmbox-speedy notheme',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'cmbox-delete notheme',
image = 'Ambox warning pn.svg'
},
content = {
class = 'cmbox-content notheme',
image = 'Ambox important.svg'
},
style = {
class = 'cmbox-style notheme',
image = 'Edit-clear.svg'
},
move = {
class = 'cmbox-move notheme',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'cmbox-protection notheme',
image = 'Padlock-silver-medium.svg'
},
notice = {
class = 'cmbox-notice notheme',
image = 'Information icon4.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'cmbox'},
imageEmptyCell = true,
useCollapsibleTextFields = true,
templatestyles = 'Module:Message box/cmbox.css',
},
fmbox = {
types = {
warning = {
class = 'fmbox-warning',
image = 'Ambox warning pn.svg'
},
editnotice = {
class = 'fmbox-editnotice',
image = 'Information icon4.svg'
},
system = {
class = 'fmbox-system',
image = 'Information icon4.svg'
}
},
default = 'system',
showInvalidTypeError = true,
classes = {'fmbox'},
imageEmptyCell = false,
imageRightNone = false,
useCollapsibleTextFields = true,
templatestyles = 'Module:Message box/fmbox.css',
},
imbox = {
types = {
speedy = {
class = 'imbox-speedy',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'imbox-delete',
image = 'Ambox warning pn.svg'
},
content = {
class = 'imbox-content',
image = 'Ambox important.svg'
},
style = {
class = 'imbox-style',
image = 'Edit-clear.svg'
},
move = {
class = 'imbox-move',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'imbox-protection',
image = 'Padlock-silver-medium.svg'
},
license = {
class = 'imbox-license licensetpl',
image = 'Imbox license.png' -- @todo We need an SVG version of this
},
featured = {
class = 'imbox-featured',
image = 'Cscr-featured.svg'
},
notice = {
class = 'imbox-notice',
image = 'Information icon4.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'imbox'},
imageEmptyCell = true,
below = true,
useCollapsibleTextFields = true,
templateCategory = 'Шаблоны:Шаблоны-сообщения для файлов',
templatestyles = 'Module:Message box/imbox.css',
},
ombox = {
types = {
speedy = {
class = 'ombox-speedy',
image = 'OOjs UI icon alert-destructive.svg'
},
delete = {
class = 'ombox-delete',
image = 'OOjs UI icon alert-destructive.svg'
},
content = {
class = 'ombox-content',
image = 'OOjs UI icon notice-warning.svg'
},
style = {
class = 'ombox-style',
image = 'Edit-clear.svg'
},
move = {
class = 'ombox-move',
image = 'Imbox move.png'
},
protection = {
class = 'ombox-protection',
image = 'Imbox protection.png'
},
notice = {
class = 'ombox-notice',
image = 'OOjs UI icon info-progressive.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'ombox'},
allowSmall = true,
imageEmptyCell = true,
imageRightNone = true,
useCollapsibleTextFields = true,
templatestyles = 'Module:Message box/ombox.css',
},
tmbox = {
types = {
speedy = {
class = 'tmbox-speedy notheme',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'tmbox-delete notheme',
image = 'Ambox warning pn.svg'
},
content = {
class = 'tmbox-content notheme',
image = 'Ambox important.svg'
},
style = {
class = 'tmbox-style notheme',
image = 'Edit-clear.svg'
},
move = {
class = 'tmbox-move notheme',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'tmbox-protection notheme',
image = 'Padlock-silver-medium.svg'
},
notice = {
class = 'tmbox-notice notheme',
image = 'Information icon4.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'tmbox'},
allowSmall = true,
imageRightNone = true,
imageEmptyCell = true,
imageEmptyCellStyle = true,
useCollapsibleTextFields = true,
templateCategory = 'Шаблоны:Шаблоны-сообщения для страниц обсуждений',
templatestyles = 'Module:Message box/tmbox.css',
}
}
dd71cfc9b05d5244df926bfe86dfdb7ad0e0ff85
Модуль:Navbar
828
87
148
2024-07-08T20:00:10Z
ruwiki>Putnik
0
более контрастная серая иконка шестерёнки в тёмной теме
Scribunto
text/plain
local p = {}
local hlist = 'Template:Flatlist/styles.css'
local templatestyles = 'Module:Navbar/styles.css'
local getArgs
function p._ruwikiNavbar( args )
local titleText = args[ 1 ] or (':' .. mw.getCurrentFrame():getParent():getTitle())
local title = mw.title.new(mw.text.trim(titleText), 'Template');
if not title then
error('Invalid title ' .. titleText)
end
local whiteColorDefs = {
['#fff'] = true,
['#ffffff'] = true,
['white'] = true,
}
local fontColor = args.fontcolor and args.fontcolor:lower()
local isWhite = fontColor and whiteColorDefs[ fontColor ] == true
local fontStyle = args.fontstyle and mw.text.unstripNoWiki( args.fontstyle:lower() )
if not isWhite and fontStyle then
local styleratio = require( 'Module:Color contrast' )._styleratio
isWhite = styleratio( {
fontStyle .. '; color:#666;',
'',
'#666'
} ) < 3.66
end
local isTemplate = title.namespace == 10
local altText = string.format(
'Перейти %s «%s»',
isTemplate and 'к шаблону' or 'на страницу',
mw.text.split( isTemplate and title.text or title.fullText, '#' )[ 1 ]
)
return string.format(
'[[Файл:Wikipedia interwiki section gear icon%s.svg|14px|class=noprint%s|link=%s|%s]]',
isWhite and ' white' or '',
isWhite and '' or ' skin-invert-image',
tostring( title ),
altText
)
end
function p.ruwikiNavbar(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
return p._ruwikiNavbar(getArgs(frame))
end
function p._navbar(args)
local titleArg = 1
if args.collapsible then
titleArg = 2
if not args.plain then
args.mini = 1
end
if args.fontcolor then
args.fontstyle = 'color:' .. args.fontcolor .. ';'
end
args.style = 'float:left; text-align:left; white-space:nowrap;'
end
if args[titleArg] == 'off' then
return
end
local titleText = args[titleArg] or (':' .. mw.getCurrentFrame():getParent():getTitle())
local title = mw.title.new(mw.text.trim(titleText), 'Template');
if not title then
error('Invalid title ' .. titleText)
end
local talkpage = title.talkPageTitle and title.talkPageTitle.fullText or '';
local tag
if args.nodiv then
tag = 'span'
else
tag = 'div'
end
local div = mw.html.create():tag(tag)
div
:addClass('navbar hlist plainlinks noprint')
:attr('data-navboxnavigation-link', '0')
:cssText(args.style)
if args.mini then div:addClass('navbar-mini') end
if not (args.mini or args.plain) then
div
:tag('span')
:addClass('navbar-boxtext')
:cssText(args.fontstyle)
:wikitext(args.text or 'Шаблон:')
:wikitext(' ')
end
local ul = div:tag('ul');
if args.brackets then
ul:addClass('navbar-brackets')
end
ul
:tag('li')
:addClass('nv-view')
:wikitext('[[' .. title.fullText .. '|')
:tag(args.mini and 'abbr' or 'span')
:addClass(args.mini and 'navbar-mini-abbr')
:attr('title', 'Просмотр этого шаблона')
:cssText(args.fontstyle)
:wikitext(args.mini and 'п' or 'просмотр')
:done()
:wikitext(']]')
:done()
:tag('li')
:addClass('nv-talk')
:wikitext('[[' .. talkpage .. '|')
:tag(args.mini and 'abbr' or 'span')
:attr('title', 'Обсуждение этого шаблона')
:cssText(args.fontstyle)
:wikitext(args.mini and 'о' or 'обсуждение')
:done()
:wikitext(']]');
if not args.noedit then
ul
:tag('li')
:addClass('nv-edit')
:wikitext('[[Special:EditPage/' .. title.fullText .. '|')
:tag(args.mini and 'abbr' or 'span')
:attr('title', 'Править этот шаблон')
:cssText(args.fontstyle)
:wikitext(args.mini and 'р' or 'править')
:done()
:wikitext(']]');
end
if args.collapsible then
div:done()
:tag('span')
:addClass( args.mini and 'navbar-ct-mini' or 'navbar-ct-full' )
:cssText(args.fontstyle)
:wikitext(args[1])
end
local frame = mw.getCurrentFrame()
return frame:extensionTag{
name = 'templatestyles', args = { src = hlist }
} .. frame:extensionTag{
name = 'templatestyles', args = { src = templatestyles }
} .. tostring(div:done())
end
function p.navbar(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
return p._navbar(getArgs(frame))
end
return p
695777e4dafbd5f7bf8b4f35d8db9349d08a363d
Модуль:Wikidata/doc
828
208
464
2024-07-28T13:08:16Z
ruwiki>Putnik
0
добавлены тесты
wikitext
text/x-wiki
{{СИШ}}
{{module rating|p}}
{{TOC right}}
Используется в {{tl|Wikidata}} (см. описания параметров там же). Настраивается при помощи [[Модуль:Wikidata/config]].
Прежде чем вносить какие-либо изменения в данный модуль, просьба оттестировать их в [[Модуль:Wikidata/песочница|/песочнице]]. Обратите внимание, что не всё корректно работает в песочнице.
== Общие сведения ==
Функции данного модуля не предназначены для прямого вызова из шаблонов карточек или других модулей, не являющихся функциями расширения данного. Для вызова из шаблонов карточек используйте шаблон {{tl|wikidata}} или один из специализированных шаблонов для свойств. Для вызова функций Викиданных предназначенных для отображения чаще всего достаточно вызова <code>frame:expandTemplate{}</code> с вызовом шаблона, ответственного за отрисовку свойства. С другой стороны, вызов определённых функций модуля (в основном это касается <code>getEntity()</code>) может в будущем стать предпочтительным. Данный Lua-функционал в любом случае стоит рассматривать как unstable с точки зрения сохранения совместимости на уровне кода (вместе с соответствующими функциями API для Wikibase Client).
Далее описывается внутренняя документация. Названия функций и параметров могут изменяться. При их изменении автор изменений обязан обновить шаблон {{tl|wikidata}} и специализированные шаблоны свойств. Изменения в других местах, если кто-то всё-таки вызывает функции модуля напрямую, остаются на совести автора «костыля». Итак, при вызове шаблона {{tl|wikidata}} или специализированного шаблона свойства управление отдаётся на функцию formatStatements, которая принимает frame. Из frame достаются следующие опции, которые так или иначе передаются в остальные функции:
* <code>plain</code> — булевый переключатель (по умолчанию false). Если true, результат совпадает с обычным вызовом <code><nowiki>{{#property:pNNN}}</nowiki></code> (по факту им и будет являться)
* <code>references</code> — булевый переключатель (по умолчанию true). Если true, после вывода значения параметра дополнительно выводит ссылки на источники, указанные в Викиданных. Для вывода используется [[Модуль:Sources]]. Обычно отключается для тех свойств, которые являются «самоописываемыми», например, внешними идентификаторами или ссылками (когда такая ссылка является доказательством своей актуальности), например, идентификаторы IMDb.
* <code>value</code> — значение, которое надо выводить ''вместо'' значений из Викиданных (используется, если что-то задано уже в карточке в виде т. н. локального свойства)
По умолчанию модуль поддерживает вывод следующих значений без дополнительных настроек:
* географические координаты (coordinates)
* количественные значения (quantity)
* моноязычный текст (monolingualtext)
* строки (string)
* даты (time)
Остальные типы данных требуют указания функции форматирования значения.
== Кастомизация ==
Поддерживаются три типа параметров-функций, которые дополнительно указывают, как надо форматировать значения:
* <code>property-module</code>, <code>property-function</code> — название модуля и функции модуля, которые отвечают за форматирование вывода массива значений ''свойства'' (property) с учётом квалификаторов, ссылок и прочего. Например, оформляет множество выводов в таблицу или график. Характерные примеры:
** вывод таблицы и графика населения в {{tl|wikidata/Population}} и [[Модуль:Wikidata/Population]].
*: Спецификация функции: <code>function p.…( context, options )</code>, поведение по умолчанию: [[Модуль:Wikidata#formatPropertyDefault]].
* <code>claim-module</code>, <code>claim-function</code> — название модуля и функции модуля, которые отвечают за форматирование вывода значения ''свойства'' (statement, claim) с учётом квалификаторов, ссылок и прочего. Может, например, дополнительно к основному значению (main snak) вывести значения квалификаторов. Характерные примеры:
** вывод вышестоящих административных единиц и страны в [[Модуль:Wikidata/Places]];
** вывод авторов латинского названия и даты публикации в [[Модуль:Wikidata/Biology]];
** вывод операционной системы и даты релиза в [[Модуль:Wikidata/Software]];
** вывод количества и даты, на которую оно верно, в [[Модуль:Wikidata/number]];
*: Спецификация функции: <code>function p.…( context, options, statement )</code>
* <code>value-module</code>, <code>value-function</code> — название модуля и функции модуля, которые отвечают за форматирование ''значения'' (snak, snak data value), в зависимости от контекста, как значений свойства, так и значений квалификатора (если вызывается из <code>claim-module/claim-function</code>). Необходимо для изменения отображения свойства, например, генерации викиссылки вместо простой строки или даже вставки изображения вместо отображения имени файла изображения (так как ссылки на изображения хранятся как строки). Характерные примеры:
** вывод ссылки на [[Викисклад]] в [[Модуль:Wikidata/media]]
** вывод ссылок на внешние сайты в [[Модуль:Wikidata/link]]
*: Спецификация функции: <code>function p.…( value, options )</code>
=== Заготовки функций ===
{{Скрытый
| Заголовок = property-function
| Содержание = <syntaxhighlight lang="lua">
function p.formatSomeProperty( context, options )
local claims = context.selectClaims( options, options.property );
if claims == nil then
return ''
end
local formattedStatements = {}
for _, claim in ipairs( claims ) do
local formattedStatement = context.formatStatement( options, claim )
-- local formattedStatement = p.formatSomeStatement( context, options, claim )
if ( formattedStatement and formattedStatement ~= '' ) then
formattedStatement = context.wrapStatement( formattedStatement, options.property, claim.id )
table.insert( formattedStatements, formattedStatement )
end
end
return mw.text.listToText( formattedStatements, options.separator, options.conjunction )
end
</syntaxhighlight>
Также см. код метода <code>formatPropertyDefault</code> ниже, в нём присутствует больше проверок и работа параметрами вызова.
}}
{{Скрытый
| Заголовок = claim-function
| Содержание = <syntaxhighlight lang="lua">
function formatSomeClaim( context, options, statement )
local circumstances = context.getSourcingCircumstances( statement );
options.qualifiers = statement.qualifiers;
local result = context.formatSnak( options, statement.mainsnak, circumstances );
if ( result and result ~= '' and options.references ) then
result = result .. context.formatRefs( options, statement );
end
return result;
end
</syntaxhighlight>
Также см. код метода <code>formatStatementDefault</code> ниже, в нём есть пример работы с квалификаторами.
}}
{{Скрытый
| Заголовок = value-function
| Содержание = <syntaxhighlight lang="lua">
function formatSomeValue( context, options, value )
return value;
end
</syntaxhighlight>
Также см. код метода <code>formatUrlSingle</code> в модуле [[Модуль:URL]].
}}
=== Context API ===
{{Заготовка раздела|описать публичные методы, доступные через <code>context</code>.}}
==== Переменные ====
* <code>entity</code>
* <code>frame</code>
==== Методы ====
* <code>cloneOptions( options )</code>
* <code>getSourcingCircumstances( statement )</code>
* <code>formatProperty( options )</code>
* <code>formatPropertyDefault( context, options )</code>
* <code>formatSnak( options, snak, circumstances )</code>
* <code>formatStatement( options, statement )</code>
* <code>formatStatementDefault( context, options, statement )</code>
* <code>formatRefs( options, statement )</code>
* <code>formatValueDefault( context, options, value )</code>
* <code>parseTimeBoundariesFromSnak( snak )</code>
* <code>parseTimeFromSnak( snak )</code>
* <code>selectClaims( options, propertyId )</code>
* <code>wrapSnak( value, hash, attributes )</code>
* <code>wrapStatement( value, propertyId, claimId, attributes )</code>
* <code>wrapQualifier( value, qualifierId, attributes )</code>
=== Функции для форматирования ===
==== property-function ====
* [[Модуль:Wikidata/date|Wikidata/date]]::formatDateIntervalProperty
* [[Модуль:Wikidata/Medals|Wikidata/Medals]]::formatProperty
* [[Модуль:Wikidata/Software|Wikidata/Software]]::formatVersionProperty
* [[Модуль:Wikidata/P512|Wikidata/P512]]::formatAcademicDegree
* [[Модуль:Wikidata/number|Wikidata/number]]::formatPropertyWithMostRecentClaimAndIndicator
* [[Модуль:Wikidata/number|Wikidata/number]]::formatColorIndex
==== claim-function ====
* [[Модуль:Wikidata/Places|Wikidata/Places]]::formatCountryClaimWithFlag
* [[Модуль:Wikidata/Places|Wikidata/Places]]::formatPlaceWithQualifiers
* [[Модуль:Wikidata/item|Wikidata/item]]::formatEntityWithGenderClaim
* [[Модуль:Wikidata/Biology|Wikidata/Biology]]::formatTaxonNameClaim
* [[Модуль:Wikidata/item|Wikidata/item]]::applyDefaultTemplate
* [[Модуль:Wikidata/date|Wikidata/date]]::formatDateOfBirthClaim
* [[Модуль:Wikidata/date|Wikidata/date]]::formatDateOfDeathClaim
==== value-function ====
* [[Модуль:Wikidata|Wikidata]]::extractCategory
* [[Модуль:Wikidata/link|Wikidata/link]]::fromModule
* [[Модуль:Wikidata/Medals|Wikidata/Medals]]::formatValue
* [[Модуль:Wikidata/media|Wikidata/media]]::formatCommonsCategory
* [[Модуль:Wikidata/Software|Wikidata/Software]]::formatExtension
* [[Модуль:Wikidata/number|Wikidata/number]]::formatRA
* [[Модуль:Wikidata/number|Wikidata/number]]::formatDMS
* [[Модуль:Wikidata/url|Wikidata/url]]::formatUrlValue
* [[Модуль:Wikidata/url|Wikidata/url]]::formatLangRefs
== Тесты ==
{{Скрытый
| Заголовок = [[Модуль:Wikidata/tests]]
| Содержание = {{#invoke:Wikidata/tests|run_tests}}
}}
== См. также ==
* [[Модуль:Wikibase]]
* Независимые иноязычные аналоги:
** [[:fr:Module:Wikidata]]
** [[:ca:Mòdul:Wikidades]]
** [[:it:Modulo:Wikidata]]
** [[:de:Modul:Wikidata]]
** [[:en:Module:WikidataIB]]
** [[:en:Module:Wd]]
<noinclude>
[[Категория:Модули:Документация]]
</noinclude>
<includeonly>
[[Категория:Модули:Викиданные]]
</includeonly>
1e00ff235ce39f7fd8e5927f57fda177a193a7a6
Модуль:Wikidata/tests
828
210
468
2024-07-28T14:14:19Z
ruwiki>QBA-bot
0
Защитил страницу [[Модуль:Wikidata/tests]]: критический шаблон или модуль (каскадная защита) ([Редактирование=только автоподтверждённые] (бессрочно) [Переименование=только автоподтверждённые] (бессрочно))
Scribunto
text/plain
-- Unit tests for [[Module:URL]]. Click talk page to run tests.
local p = require( 'Module:UnitTests' )
local wd = require( 'Module:Wikidata' )
local getSnak = function( timeString )
return {
datatype = "time",
datavalue = {
type = "time",
value = {
after = 0,
before = 0,
calendarmodel = "http://www.wikidata.org/entity/Q1985727",
precision = 11,
time = timeString,
timezone = 0,
},
},
hash = "33bd9a339157ce7b3d74cb10d73bc23529c9a7f3",
property = "P585",
snaktype = "value",
}
end
function p:test_parseTimeBoundaries()
self:equals_deep( '2000-12-31', wd._parseTimeBoundaries( '+2000-12-31T00:00:00Z', 11 ), { 978220800000, 978307199999 } )
self:equals_deep( '2001-01-01', wd._parseTimeBoundaries( '+2001-01-01T00:00:00Z', 11 ), { 978307200000, 978393599999 } )
self:equals_deep( '2001', wd._parseTimeBoundaries( '+2001-00-00T00:00:00Z', 9 ), { 978307200000, 1009843199999 } )
end
function p:test_parseTimeFromSnak()
self:equals_deep( '2000-12-31', wd._parseTimeFromSnak( getSnak( '+2000-12-31T00:00:00Z' ) ), 978220800000 )
self:equals_deep( '2001-01-01', wd._parseTimeFromSnak( getSnak( '+2001-01-01T00:00:00Z' ) ), 978307200000 )
self:equals_deep( '2001', wd._parseTimeFromSnak( getSnak( '+2001-00-00T00:00:00Z' ) ), 978307200000 )
end
return p
a49c6e32801a352e27ec0dee7b1af3c93a0f5c10
Шаблон:Docpage
10
178
398
2024-07-29T17:18:37Z
ruwiki>Putnik
0
поддержка тёмной темы
wikitext
text/x-wiki
<includeonly>{{#ifeq: {{SUBPAGENAME}} | doc
| {{fmbox
| class = hlist nowraplinks
| style = margin-bottom:1em; background:var(--background-color-progressive-subtle, #eaf3ff); color:inherit; border:1px solid var(--border-color-content-added, #a3d3ff);
| image = [[Файл:OOjs UI icon info.svg|24px|link=|alt=|class=skin-invert-image]]
| text = <div>
* [[:{{#titleparts: {{SUBJECTPAGENAME}} | -1 }}]]
* [[:{{SUBJECTPAGENAME}}|Документация]]
* [[{{#titleparts: {{TALKPAGENAME}} | -1 }}|Обсуждение]]
* [[Служебная:Whatlinkshere/{{#titleparts: {{SUBJECTPAGENAME}} | -1 }}|Где используется]] {{#ifeq: {{NAMESPACE}} | {{ns:Template}} |
** {{Параметры шаблона|{{#titleparts: {{PAGENAME}} | -1 }}}}
}}</div><!--
-->{{#if: {{{nocat|}}} || {{#ifexist: {{NAMESPACE}}:{{BASEPAGENAME}} || [[Категория:Шаблоны:Документация несуществующих шаблонов]] }} }}
}}{{#if: {{{nocat|}}} || {{#ifeq: {{NAMESPACE}}
| Модуль
| [[Категория:Модули:Документация]]
| [[Категория:Шаблоны:Документация]]
}}
}}
}}</includeonly><noinclude>{{doc}}</noinclude>
9b09d5b771c19e45bd038d248dcf31e500e436ce
Шаблон:Родственный проект/styles.css
10
288
737
2024-07-29T20:40:07Z
ruwiki>Putnik
0
убрал !important
sanitized-css
text/css
.ts-Родственный_проект,
.ts-Родственный_проект.metadata:not(.notheme) {
background: var(--background-color-neutral-subtle, #f8f9fa);
border: 1px solid var(--border-color-base, #a2a9b1);
clear: right;
float: right;
font-size: 90%;
margin: 0 0 1em 1em;
padding: .4em;
max-width: 19em;
width: 19em;
line-height: 1.5;
}
.ts-Родственный_проект th,
.ts-Родственный_проект td {
padding: .2em 0;
vertical-align: middle;
}
.ts-Родственный_проект th + td {
padding-left: .4em;
}
@media (max-width: 719px) {
.ts-Родственный_проект {
width: auto;
margin-left: 0;
margin-right: 0;
}
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
50b08ba20d75d9b717bc6920475793f259cd3af1
Шаблон:Рейтинг модуля
10
93
158
2024-07-29T20:44:27Z
ruwiki>Putnik
0
поддержка тёмной темы
wikitext
text/x-wiki
{{Module other|{{ombox
| type = notice
| image = {{#switch: {{{1|}}}
| pre-alpha | prealpha | pa | пре-альфа = [[File:Ambox warning blue construction.svg|40x40px|link=]]
| alpha | a | альфа = [[File:Greek lc alpha icon.svg|26x26px|link=|class=skin-invert-image]]
| beta | b | бета = [[File:Greek lc beta icon.svg|40x40px|link=|class=skin-invert-image]]
| release | r | general | g | готов = [[File:Green check.svg|40x40px|link=]]
| protected | protect | p | защищен = [[File:Padlock-silver.svg|40x40px|link=]]
}}
| style =
| textstyle =
| text = {{#switch: {{{1|}}}
| pre-alpha | prealpha | pa | пре-альфа = Этот модуль оценён как [[:Категория:Модули:Пре-альфа версии|пре-альфа-версия]]. Он не закончен и может находиться в разработке. Он не должен использоваться в статьях. Модули остаются в этой стадии до тех пор, пока автор или кто-либо иной не сочтёт их структуру удовлетворительной.<!--
-->{{#switch: {{SUBPAGENAME}}|doc|sandbox=<!-- No category for /doc or /sandbox subpages -->
| {{#ifeq: {{{nocat|}}} | true | <!-- No category if user sets nocat=true --> | [[Категория:Модули:Пре-альфа версии]] }}
}}
| alpha | a | альфа = Этот модуль оценён как [[:Категория:Модули:Альфа-версии|альфа-версия]]. Он готов для тестирований и может быть использован на небольшом количестве страниц для обнаружения проблем. Предложения по изменениям и дополнениям приветствуются.<!--
-->{{#switch: {{SUBPAGENAME}}|doc|sandbox=<!-- No category for /doc or /sandbox subpages -->
| {{#ifeq: {{{nocat|}}} | true | <!-- No category if user sets nocat=true --> | [[Категория:Модули:Альфа-версии]] }}
}}
| beta | b | бета = Этот модуль оценён как [[:Категория:Модули:Бета-версии|бета-версия]]. Он готов для широкого применения, но должен применяться с осторожностью.<!--
-->{{#switch: {{SUBPAGENAME}}|doc|sandbox=<!-- No category for /doc or /sandbox subpages -->
| {{#ifeq: {{{nocat|}}} | true | <!-- No category if user sets nocat=true --> | [[Категория:Модули:Бета-версии]] }}
}}
| release | r | general | g | готов = Этот модуль оценён как [[:Категория:Модули:Стабильные|готовый к использованию]]. Предполагается, что все баги устранены и он готов для широкого использования. Его можно указывать на справочных страницах и рекомендовать к использованию новым участникам. Для его изменения и тестирования, пожалуйста, [[ВП:ТЕСТЫ|используйте песочницу]].<!--
-->{{#switch: {{SUBPAGENAME}}|doc|sandbox=<!-- No category for /doc or /sandbox subpages -->
| {{#ifeq: {{{nocat|}}} | true | <!-- No category if user sets nocat=true --> | [[Категория:Модули:Стабильные]] }}
}}
| protected | protect | p | защищен = Этот модуль относится к [[:Категория:Модули:Критические|критическим]]. У него очень много включений или он используется с подстановкой. Из-за опасности вандализма или ошибочного редактирования он был защищён.<!--
-->{{#switch: {{SUBPAGENAME}}|doc|sandbox=<!-- No category for /doc or /sandbox subpages -->
| {{#ifeq: {{{nocat|}}} | true | <!-- No category if user sets nocat=true --> | [[Категория:Модули:Критические]] }}
}}
| #default = {{error|Рейтинг не указан или указан неправильно.}}
}}
}}|{{error|Этот шаблон должен использоваться в пространстве модулей.}}|demospace={{{demospace|<noinclude>module</noinclude>}}}}}<noinclude>{{doc}}</noinclude>
c3380f20f70295631f2614caead4cbc73c110883
Шаблон:Doc/styles.css
10
173
388
2024-08-05T07:09:06Z
ruwiki>Putnik
0
исправление кода для тёмной темы ([[phab:T369874]])
sanitized-css
text/css
.ts-doc-doc {
background-color: var(--background-color-progressive-subtle, #eaf3ff);
border: 1px solid var(--border-color-content-added, #afb6e9);
clear: both;
margin-top: 1em;
}
/* Ctrl+F ":target" in [[MediaWiki:Common.css]] */
.ts-doc-doc sup.reference:target,
.ts-doc-doc ol.references li:target,
.ts-doc-doc .highlight-target:target,
.ts-doc-doc cite:target,
.ts-doc-doc span.citation:target {
background: var(--ruwiki-background-color-blue200, #cfe3ff);
}
.ts-doc-header {
align-items: center;
background: var(--ruwiki-background-color-blue200, #cfe3ff);
display: flex;
flex-wrap: wrap;
padding: .642857em 1em .5em;
overflow: hidden;
}
.ts-doc-header .ts-tlinks-tlinks {
margin-left: auto;
}
.ts-doc-content {
padding: .214286em 1em;
}
.ts-doc-content:after {
content: '';
clear: both;
display: block;
}
.ts-doc-heading {
display: inline-block;
padding-left: 2em;
background: url(//upload.wikimedia.org/wikipedia/commons/c/ca/OOjs_UI_icon_info.svg) center left no-repeat;
background-size: contain;
font-size: small;
min-height: 1.75em;
font-weight: 600;
letter-spacing: 0.1em;
text-transform: uppercase;
}
@media screen {
html.skin-theme-clientpref-night .ts-doc-heading {
background-image: url(//upload.wikimedia.org/wikipedia/commons/c/c0/OOjs_UI_icon_info-invert.svg);
}
}
@media screen and (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os .ts-doc-heading {
background-image: url(//upload.wikimedia.org/wikipedia/commons/c/c0/OOjs_UI_icon_info-invert.svg);
}
}
.ts-doc-content > *:first-child,
.ts-doc-footer > *:first-child {
margin-top: .5em;
}
.ts-doc-content > *:last-child,
.ts-doc-footer > *:last-child {
margin-bottom: .5em;
}
.ts-doc-footer {
background-color: var(--background-color-progressive-subtle, #eaf3ff);
border: 1px solid var(--border-color-content-added, #afb6e9);
padding: .214286em 1em;
margin-top: .214286em;
margin-bottom: .214286em;
font-style: italic;
}
@media (max-width: 719px) {
.ts-doc-header {
display: block;
}
.ts-doc-header .ts-tlinks-tlinks {
float: none;
}
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
be8d912472a37a6051bee114da86f913839e7ca0
Модуль:Wikidata
828
262
685
2024-08-07T12:29:07Z
ruwiki>Putnik
0
fix
Scribunto
text/plain
---settings, may differ from project to project
local fileDefaultSize = '267x400px'
local outputReferences = true
local writingSystemElementId = 'Q8209'
local langElementId = 'Q7737'
---Ссылки на используемые модули, которые потребуются в 99% случаев загрузки страниц (чтобы иметь на виду при переименовании)
local moduleSources = require( 'Module:Sources' )
local WDS = require( 'Module:WikidataSelectors' )
---Константы
---@type string
local CONTENT_LANGUAGE_CODE = mw.language.getContentLanguage():getCode()
local p = {}
local g_config, g_frame
local formatDatavalue, formatEntityId, formatRefs, formatSnak, formatStatement,
formatStatementDefault, getSourcingCircumstances, getPropertyParams
---@param obj table
---@param target table
---@param skipEmpty boolean | nil
---@return table
local function copyTo( obj, target, skipEmpty )
for key, val in pairs( obj ) do
if skipEmpty ~= true or ( val ~= nil and val ~= '' ) then
target[ key ] = val
end
end
return target
end
---@param prev number | nil
---@param next number | nil
---@return number | nil
local function min( prev, next )
if prev == nil or prev > next then
return next
end
return prev
end
---@param prev number | nil
---@param next number | nil
---@return number | nil
local function max( prev, next )
if prev == nil or prev < next then
return next
end
return prev
end
---@param section string
---@param code string
---@return any | nil
local function getConfig( section, code )
if g_config == nil then
g_config = require( 'Module:Wikidata/config' )
end
if not g_config then
g_config = {}
end
if not section then
return g_config
end
if not code then
return g_config[ section ] or {}
end
if not g_config[ section ] then
return nil
end
return g_config[ section ][ code ]
end
---@param code string
---@param sortKey string | nil
---@return string
local function getCategoryByCode( code, sortKey )
local value = getConfig( 'categories', code )
if not value or value == '' then
return ''
end
if sortKey ~= nil then
return '[[Category:' .. value .. '|' .. sortKey .. ']]'; -- экранировать?
else
return '[[Category:' .. value .. ']]'
end
end
---@param isoStr string | table
---@return table | nil
local function splitISO8601( isoStr )
if 'table' == type( isoStr ) then
if isoStr.args and isoStr.args[ 1 ] then
isoStr = '' .. isoStr.args[ 1 ]
else
return 'unknown argument type: ' .. type( isoStr ) .. ': ' .. table.tostring( isoStr )
end
end
local Y, M, D = ( function( str )
local pattern = "(%-?%d+)%-(%d+)%-(%d+)T"
local _Y, _M, _D = mw.ustring.match( str, pattern )
return tonumber( _Y ), tonumber( _M ), tonumber( _D )
end )( isoStr )
local h, m, s = ( function( str )
local pattern = "T(%d+):(%d+):(%d+)%Z"
local _H, _M, _S = mw.ustring.match( str, pattern )
return tonumber( _H ), tonumber( _M ), tonumber( _S )
end )( isoStr )
local oh, om = ( function( str )
if str:sub(-1) == "Z" then -- ends with Z, Zulu time
return 0, 0
end
-- matches ±hh:mm, ±hhmm or ±hh; else returns nils
local pattern = "([-+])(%d%d):?(%d?%d?)$"
local sign, oh, om = mw.ustring.match( str, pattern )
sign, oh, om = sign or "+", oh or "00", om or "00"
return tonumber( sign .. oh ), tonumber( sign .. om )
end )( isoStr )
return { year=Y, month=M, day=D, hour=( h + oh ), min=( m + om ), sec=s }
end
---Внутренняя функции для получения границ временного диапазона
---@param time string
---@param precision number
---@return table | nil
function p._parseTimeBoundaries( time, precision )
local s = splitISO8601( time )
if not s then
return nil
end
if precision >= 0 and precision <= 8 then
local powers = { 1000000000 , 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10 }
local power = powers[ precision + 1 ]
local left = s.year - ( s.year % power )
return { tonumber( os.time( { year=left, month=1, day=1, hour=0, min=0, sec=0 } ) ) * 1000,
tonumber( os.time( { year=left + power - 1, month=12, day=31, hour=29, min=59, sec=58 } ) ) * 1000 + 1999 }
end
if precision == 9 then
return { tonumber( os.time( { year=s.year, month=1, day=1, hour=0, min=0, sec=0} )) * 1000,
tonumber( os.time( { year=s.year, month=12, day=31, hour=23, min=59, sec=58} )) * 1000 + 1999 }
end
if precision == 10 then
local lastDays = { 31, 28.25, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
local lastDay = lastDays[ s.month ]
return { tonumber( os.time( { year=s.year, month=s.month, day=1, hour=0, min=0, sec=0 } ) ) * 1000,
tonumber( os.time( { year=s.year, month=s.month, day=lastDay, hour=23, min=59, sec=58 } ) ) * 1000 + 1999 }
end
if precision == 11 then
return { tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=0, min=0, sec=0 } ) ) * 1000,
tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=23, min=59, sec=58 } ) ) * 1000 + 1999 }
end
if precision == 12 then
return { tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=0, sec=0 } ) ) * 1000,
tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=59, sec=58 } ) ) * 1000 + 1999 }
end
if precision == 13 then
return { tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=s.min, sec=0 } ) ) * 1000,
tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=s.min, sec=58 } ) ) * 1000 + 1999 }
end
if precision == 14 then
local t = tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=s.min, sec=0 } ) )
return { t * 1000, t * 1000 + 999 }
end
error( 'Unsupported precision: ' .. precision )
end
---Внутренняя функция для получения числового значения времени из snak'а
---@param table snak
---@return number | nil
function p._parseTimeFromSnak( snak )
if snak and snak.datavalue and snak.datavalue.value and snak.datavalue.value.time then
local timeData = splitISO8601( tostring( snak.datavalue.value.time ) )
timeData.month = math.max( timeData.month, 1 )
timeData.day = math.max( timeData.day, 1 )
return tonumber( os.time( timeData ) ) * 1000
end
return nil
end
---Функция для формирования категории на основе wikidata/config
---@param options table
---@param entityId string
---@return string
local function extractCategory( options, entityId )
if not entityId or not options.category or options.nocat then
return ''
end
if type( entityId ) ~= 'string' then
entityId = entityId.id
end
local claims = WDS.load( entityId, options.category )
if not claims then
return ''
end
for _, claim in pairs( claims ) do
if claim
and claim.mainsnak
and claim.mainsnak.datavalue
and claim.mainsnak.datavalue.type == 'wikibase-entityid'
then
local catEntityId = claim.mainsnak.datavalue.value.id
local wbStatus, catSiteLink = pcall( mw.wikibase.getSitelink, catEntityId )
if wbStatus and catSiteLink then
return '[[' .. catSiteLink .. ']]'
end
end
end
return ''
end
---Преобразует строку в булевое значение
---@param valueToParse string
---@return boolean Преобразованное значение, если его удалось распознать, или defaultValue во всех остальных случаях
local function toBoolean( valueToParse, defaultValue )
if valueToParse ~= nil then
if valueToParse == false or valueToParse == '' or valueToParse == 'false' or valueToParse == '0' then
return false
end
return true
end
return defaultValue
end
---Обрачивает отформатированное значение в инлайновый или блочный тег.
---@param value string value
---@param attributes table of attributes
---@return string HTML tag with value
local function wrapValue( value, attributes )
local tagName = 'span'
local spacer = ''
if string.match( value, '\n' )
or string.match( value, '<t[dhr][ >]' )
or string.match( value, '<div[ >]' )
or string.find( value, 'UNIQ%-%-imagemap' )
then
tagName = 'div'
spacer = '\n'
end
local attrString = ''
for key, val in pairs( attributes or {} ) do
local _key = mw.text.trim( key )
local _value = mw.text.encode( mw.text.trim( val ) )
attrString = attrString .. _key .. '="' .. _value .. '" '
end
return '<' .. tagName .. ' ' .. attrString .. '>' .. spacer .. value .. '</' .. tagName .. '>'
end
---Wraps formatted snak value into HTML tag with attributes.
---@param value string value of snak
---@param hash string
---@param attributes table of extra attributes
---@return string HTML tag with value
local function wrapSnak( value, hash, attributes )
local newAttributes = mw.clone( attributes or {} )
newAttributes[ 'class' ] = ( newAttributes[ 'class' ] or '' ) .. ' wikidata-snak'
if hash then
newAttributes[ 'data-wikidata-hash'] = hash
else
newAttributes[ 'class' ] = newAttributes[ 'class' ] .. ' wikidata-main-snak'
end
return wrapValue( value, newAttributes )
end
---Wraps formatted statement value into HTML tag with attributes.
---@param value string value of statement
---@param propertyId string PID of property
---@param claimId string ID of claim or nil for local value
---@param attributes table of extra attributes
---@return string HTML tag with value
local function wrapStatement( value, propertyId, claimId, attributes )
local newAttributes = mw.clone( attributes or {} )
newAttributes[ 'class' ] = newAttributes[ 'class' ] or ''
newAttributes[ 'data-wikidata-property-id' ] = string.upper( propertyId )
if claimId then
newAttributes[ 'class' ] = newAttributes[ 'class' ] .. ' wikidata-claim'
newAttributes[ 'data-wikidata-claim-id' ] = claimId
else
newAttributes[ 'class' ] = newAttributes[ 'class' ] .. ' no-wikidata'
end
return wrapValue( value, newAttributes )
end
---Wraps formatted qualifier's statement value into HTML tag with attributes.
---@param value string value of qualifier's statement
---@param qualifierId string PID of qualifier
---@param attributes table of extra attributes
---@return string HTML tag with value
local function wrapQualifier( value, qualifierId, attributes )
local newAttributes = mw.clone( attributes or {} )
newAttributes[ 'data-wikidata-qualifier-id' ] = string.upper( qualifierId )
return wrapValue( value, newAttributes )
end
---Функция для получения сущности (еntity) для текущей страницы
---Подробнее о сущностях см. d:Wikidata:Glossary/ru
---@param id string Идентификатор (типа P18, Q42)
---@return table Таблица, элементы которой индексируются с нуля
local function getEntityFromId( id )
local entity
local wbStatus
if id then
wbStatus, entity = pcall( mw.wikibase.getEntity, id )
else
wbStatus, entity = pcall( mw.wikibase.getEntity )
end
return entity
end
---Внутренняя функция для формирования сообщения об ошибке
---@param key string Ключ элемента в таблице config.errors (например entity-not-found)
---@return void
local function throwError( key )
error( getConfig( 'errors', key ) )
end
---Функция для получения идентификатора сущностей
---@param value table
---@return string
local function getEntityIdFromValue( value )
local prefix = ''
if value[ 'entity-type' ] == 'item' then
prefix = 'Q'
elseif value[ 'entity-type' ] == 'property' then
prefix = 'P'
else
throwError( 'unknown-entity-type' )
end
return prefix .. value[ 'numeric-id' ]
end
---Проверка на наличие специализированной функции в опциях
---@param options table
---@param prefix string
---@return function
local function getUserFunction( options, prefix, defaultFunction )
-- проверка на указание специализированных обработчиков в параметрах,
-- переданных при вызове
if options[ prefix .. '-module' ] or options[ prefix .. '-function' ] then
-- проверка на пустые строки в параметрах или их отсутствие
if not options[ prefix .. '-module' ] or not options[ prefix .. '-function' ] then
throwError( 'unknown-' .. prefix .. '-module' )
end
-- динамическая загруза модуля с обработчиком указанным в параметре
local formatter = require( 'Module:' .. options[ prefix .. '-module' ] )
if formatter == nil then
throwError( prefix .. '-module-not-found' )
end
local fun = formatter[ options[ prefix .. '-function' ] ]
if fun == nil then
throwError( prefix .. '-function-not-found' )
end
return fun
end
return defaultFunction
end
---Выбирает свойства по property id, дополнительно фильтруя их по рангу
---@param context table
---@param options table
---@param propertySelector string
---@return table | nil
local function selectClaims( context, options, propertySelector )
if not context then error( 'context not specified' ); end
if not options then error( 'options not specified' ); end
if not options.entityId then error( 'options.entity is missing' ); end
if not propertySelector then error( 'propertySelector not specified' ); end
local result = WDS.load( options.entityId, propertySelector )
if not result or #result == 0 then
return nil
end
if options.limit and options.limit ~= '' and options.limit ~= '-' then
local limit = tonumber( options.limit, 10 )
while #result > limit do
table.remove( result )
end
end
return result
end
---Функция для получения значения свойства элемента в заданный момент времени.
---@param entityId string
---@param boundaries table Временные границы
---@param propertyIds table<string>
---@param selectors table<string>
---@return table Таблица соответствующих значений свойства
local function getPropertyInBoundaries( context, entityId, boundaries, propertyIds, selectors )
if type( entityId ) ~= 'string' then error( 'type of entityId argument expected string, but was ' .. type(entityId)); end
local results = {}
if not propertyIds or #propertyIds == 0 then
return results
end
for i, propertyId in ipairs( propertyIds ) do
local selector
if selectors ~= nil then
selector = selectors[ i ] or selectors[ propertyId ] or propertyId
else
selector = propertyId
end
local fakeAllClaims = {}
fakeAllClaims[ propertyId ] = mw.wikibase.getAllStatements( entityId, propertyId )
local filteredClaims = WDS.filter( fakeAllClaims, selector .. '[rank:preferred, rank:normal]' )
if filteredClaims then
for _, claim in pairs( filteredClaims ) do
if not boundaries then
if not claim.qualifiers or not claim.qualifiers.P582 then
table.insert( results, claim.mainsnak )
end
else
local startBoundaries = p.getTimeBoundariesFromQualifier( context.frame, context, claim, 'P580' )
local endBoundaries = p.getTimeBoundariesFromQualifier( context.frame, context, claim, 'P582' )
if ( startBoundaries == nil or startBoundaries[ 1 ] <= boundaries[ 1 ] ) and
( endBoundaries == nil or endBoundaries[ 1 ] >= boundaries[ 2 ] )
then
table.insert( results, claim.mainsnak )
end
end
end
end
if #results > 0 then
break
end
end
return results
end
---@param context table
---@param propertyId string
---@return table | nil
function p.getTimeBoundariesFromProperty( context, propertyId )
local dateClaims = WDS.filter( context.entity.claims, propertyId )
if not dateClaims or #dateClaims == 0 then
return nil;
end
-- only support exact date so far, but need improvment
local left = nil
local right = nil
for _, claim in pairs( dateClaims ) do
if not claim.mainsnak then
return nil
end
local boundaries = context.parseTimeBoundariesFromSnak( claim.mainsnak )
if not boundaries then
return nil
end
left = min( left, boundaries[ 1 ] )
right = max( right, boundaries[ 2 ] )
end
if not left or not right then
return nil
end
return { left, right }
end
---@param context table
---@param propertyIds table<string>
---@return table | nil
function p.getTimeBoundariesFromProperties( context, propertyIds )
for _, propertyId in ipairs( propertyIds ) do
local result = p.getTimeBoundariesFromProperty( context, propertyId );
if result then
return result
end
end
return nil
end
---@param context table
---@param statement table
---@param qualifierId string
---@return table | nil
function p.getTimeBoundariesFromQualifier( _, context, statement, qualifierId )
-- only support exact date so far, but need improvement
local left, right
if statement.qualifiers and statement.qualifiers[ qualifierId ] then
for _, qualifier in pairs( statement.qualifiers[ qualifierId ] ) do
local boundaries = context.parseTimeBoundariesFromSnak( qualifier )
if not boundaries then
return nil
end
left = min( left, boundaries[ 1 ] )
right = max( right, boundaries[ 2 ] )
end
end
if not left or not right then
return nil
end
return { left, right }
end
---@param _ table
---@param context table
---@param statement table
---@param qualifierIds table<string>
---@return table | nil
function p.getTimeBoundariesFromQualifiers( _, context, statement, qualifierIds )
if not qualifierIds then
qualifierIds = { 'P582', 'P580', 'P585' }
end
for _, qualifierId in pairs( qualifierIds ) do
local result = p.getTimeBoundariesFromQualifier( _, context, statement, qualifierId )
if result then
return result
end
end
return nil
end
---@type table<string>
local getLabelWithLang_DEFAULT_PROPERTIES = { 'P1813', 'P1448', 'P1705' }
---@type table<string>
local getLabelWithLang_DEFAULT_SELECTORS = {
'P1813[language:' .. CONTENT_LANGUAGE_CODE .. '][!P282,P282:' .. writingSystemElementId .. '][!P3831,P3831:Q105690470]',
'P1448[language:' .. CONTENT_LANGUAGE_CODE .. '][!P282,P282:' .. writingSystemElementId .. '][!P3831,P3831:Q105690470]',
'P1705[language:' .. CONTENT_LANGUAGE_CODE .. '][!P282,P282:' .. writingSystemElementId .. '][!P3831,P3831:Q105690470]'
}
---Функция для получения метки элемента в заданный момент времени.
---@param context table
---@param options table
---@param entityId string
---@param boundaries table
---@param propertyIds table
---@param selectors table<string>
---@return string, string Текстовая метка элемента, язык метки
local function getLabelWithLang( context, options, entityId, boundaries, propertyIds, selectors )
if type( entityId ) ~= 'string' then error( 'type of entityId argument expected string, but was ' .. type( entityId ) ); end
if not entityId then
return nil
end
local langCode = CONTENT_LANGUAGE_CODE
-- name from label
local label
if options.text and options.text ~= '' then
label = options.text
else
if not propertyIds then
propertyIds = getLabelWithLang_DEFAULT_PROPERTIES
selectors = getLabelWithLang_DEFAULT_SELECTORS
end
-- name from properties
local results = getPropertyInBoundaries( context, entityId, boundaries, propertyIds, selectors )
for _, result in pairs( results ) do
if result.datavalue and result.datavalue.value then
if result.datavalue.type == 'monolingualtext' and result.datavalue.value.text then
label = result.datavalue.value.text
langCode = result.datavalue.value.language
break
elseif result.datavalue.type == 'string' then
label = result.datavalue.value
break
end
end
end
if not label then
label, langCode = mw.wikibase.getLabelWithLang( entityId )
if not langCode then
return nil
end
end
end
return label, langCode
end
---@param context table
---@param options table
---@return string
local function formatPropertyDefault( context, options )
if not context then error( 'context not specified' ); end
if not options then error( 'options not specified' ); end
if not options.entityId then error( 'options.entityId missing' ); end
local claims
if options.property then -- TODO: Почему тут может не быть property?
if options.rank then -- передать настройки ранга из конфига
claims = context.selectClaims( options, options.property .. options.rank )
else
claims = context.selectClaims( options, options.property )
end
end
if claims == nil then
return '' --TODO error?
end
-- Обход всех заявлений утверждения и с накоплением оформленных предпочтительных
-- заявлений в таблице
local formattedClaims = {}
for _, claim in pairs( claims ) do
local formattedStatement = context.formatStatement( options, claim )
-- здесь может вернуться либо оформленный текст заявления, либо строка ошибки, либо nil
if formattedStatement and formattedStatement ~= '' then
if not options.plain then
formattedStatement = context.wrapStatement( formattedStatement, options.property, claim.id )
end
table.insert( formattedClaims, formattedStatement )
end
end
-- создание текстовой строки со списком оформленых заявлений из таблицы
local out = mw.text.listToText( formattedClaims, options.separator, options.conjunction )
if out ~= '' then
if options.before then
out = options.before .. out
end
if options.after then
out = out .. options.after
end
end
return out
end
---Create context
---@param initOptions table
---@return table | nil
local function initContext( initOptions )
local context = {
entityId = initOptions.entityId,
entity = initOptions.entity,
extractCategory = extractCategory,
formatSnak = formatSnak,
formatPropertyDefault = formatPropertyDefault,
formatStatementDefault = formatStatementDefault,
getPropertyInBoundaries = getPropertyInBoundaries,
getTimeBoundariesFromProperty = p.getTimeBoundariesFromProperty,
getTimeBoundariesFromProperties = p.getTimeBoundariesFromProperties,
getTimeBoundariesFromQualifier = p.getTimeBoundariesFromQualifier,
getTimeBoundariesFromQualifiers = p.getTimeBoundariesFromQualifiers,
parseTimeFromSnak = p._parseTimeFromSnak,
getLabelWithLang = getLabelWithLang,
wrapSnak = wrapSnak,
wrapStatement = wrapStatement,
wrapQualifier = wrapQualifier,
}
context.cloneOptions = function( options )
local entity = options.entity
options.entity = nil
local newOptions = mw.clone( options )
options.entity = entity
newOptions.entity = entity
newOptions.frame = options.frame; -- На склонированном фрейме frame:expandTemplate()
return newOptions
end
context.formatProperty = function( options )
local func = getUserFunction( options, 'property', context.formatPropertyDefault )
return func( context, options )
end
context.formatStatement = function( options, statement ) return formatStatement( context, options, statement ) end
context.formatSnak = function( options, snak, circumstances ) return formatSnak( context, options, snak, circumstances ) end
context.formatRefs = function( options, statement ) return formatRefs( context, options, statement ) end
context.parseTimeBoundariesFromSnak = function( snak )
if snak and snak.datavalue and snak.datavalue.value and snak.datavalue.value.time and snak.datavalue.value.precision then
return p._parseTimeBoundaries( snak.datavalue.value.time, snak.datavalue.value.precision )
end
return nil
end
context.getSourcingCircumstances = function( statement )
return getSourcingCircumstances( statement )
end
context.selectClaims = function( options, propertyId )
return selectClaims( context, options, propertyId )
end
return context
end
---Функция для оформления утверждений (statement)
---Подробнее о утверждениях см. d:Wikidata:Glossary/ru
---@param options table
---@return string Formatted wikitext.
local function formatProperty( options )
-- Получение сущности по идентификатору
local entity = getEntityFromId( options.entityId )
if not entity then
return -- throwError( 'entity-not-found' )
end
-- проверка на присутсвие у сущности заявлений (claim)
-- подробнее о заявлениях см. d:Викиданные:Глоссарий
if not entity.claims then
return '' --TODO error?
end
-- improve options
options.frame = g_frame
options.entity = entity
options.extends = function( self, newOptions )
return copyTo( newOptions, copyTo( self, {} ) )
end
if options.i18n then
options.i18n = copyTo( options.i18n, copyTo( getConfig( 'i18n' ), {} ) )
else
options.i18n = getConfig( 'i18n' )
end
local context = initContext( options )
return context.formatProperty( options )
end
---Функция для оформления одного утверждения (statement)
---@param context table
---@param options table
---@param statement table
---@return string Formatted wikitext.
function formatStatement( context, options, statement )
if not statement then
error( 'statement is not specified or nil' )
end
if not statement.type or statement.type ~= 'statement' then
throwError( 'unknown-claim-type' )
end
local functionToCall = getUserFunction( options, 'claim', context.formatStatementDefault )
return functionToCall( context, options, statement )
end
---@param statement table
---@return table
function getSourcingCircumstances( statement )
if not statement then
error( 'statement is not specified' )
end
local circumstances = {}
if statement.qualifiers and statement.qualifiers.P1480 then
for _, qualifier in pairs( statement.qualifiers.P1480 ) do
if qualifier
and qualifier.datavalue
and qualifier.datavalue.type == 'wikibase-entityid'
and qualifier.datavalue.value
and qualifier.datavalue.value[ 'entity-type'] == 'item'
then
table.insert( circumstances, qualifier.datavalue.value.id )
end
end
end
return circumstances
end
---Функция для оформления одного утверждения (statement)
---@param context table Context.
---@param options table Parameters.
---@param statement table
---@return string Formatted wikitext.
function formatStatementDefault( context, options, statement )
if not context then error( 'context is not specified' ) end
if not options then error( 'options is not specified' ) end
if not statement then error( 'statement is not specified' ) end
local circumstances = context.getSourcingCircumstances( statement )
options.qualifiers = statement.qualifiers
local result = context.formatSnak( options, statement.mainsnak, circumstances )
if options.qualifier and statement.qualifiers and statement.qualifiers[ options.qualifier ] then
local qualifierConfig = getPropertyParams( options.qualifier, nil, {} )
if options.i18n then
qualifierConfig.i18n = options.i18n
end
if qualifierConfig.datatype == 'time' then
qualifierConfig.nolinks = true
end
local qualifierValues = {}
for _, qualifierSnak in pairs( statement.qualifiers[ options.qualifier ] ) do
local snakValue = context.formatSnak( qualifierConfig, qualifierSnak )
if snakValue and snakValue ~= '' then
table.insert( qualifierValues, snakValue )
end
end
if result and result ~= '' and #qualifierValues then
if qualifierConfig.invisible then
result = result .. table.concat( qualifierValues, ', ' )
else
result = result .. ' (' .. table.concat( qualifierValues, ', ' ) .. ')'
end
end
end
if result and result ~= '' and options.references then
result = result .. context.formatRefs( options, statement )
end
return result
end
---Функция для оформления части утверждения (snak)
---Подробнее о snak см. d:Викиданные:Глоссарий
---@param context table Context.
---@param options table Parameters.
---@param snak table
---@param circumstances table
---@return string Formatted wikitext.
function formatSnak( context, options, snak, circumstances )
circumstances = circumstances or {}
local result
if snak.snaktype == 'somevalue' then
if options[ 'somevalue' ] and options[ 'somevalue' ] ~= '' then
result = options[ 'somevalue' ]
else
result = options.i18n[ 'somevalue' ]
end
elseif snak.snaktype == 'novalue' then
if options[ 'novalue' ] and options[ 'novalue' ] ~= '' then
result = options[ 'novalue' ]
else
result = options.i18n[ 'novalue' ]
end
elseif snak.snaktype == 'value' then
result = formatDatavalue( context, options, snak.datavalue, snak.datatype )
for _, item in pairs( circumstances ) do
if options.i18n[ item ] then
result = options.i18n[ item ] .. result
end
end
else
throwError( 'unknown-snak-type' )
end
if not result or result == '' then
return nil
end
if options.plain then
return result
end
return context.wrapSnak( result, snak.hash )
end
---Функция для оформления объектов-значений с географическими координатами
---@param value string Raw value.
---@param options table Parameters.
---@return string Formatted string.
local function formatGlobeCoordinate( value, options )
-- проверка на требование в параметрах вызова на возврат сырого значения
if options[ 'subvalue' ] == 'latitude' then -- широты
return value[ 'latitude' ]
elseif options[ 'subvalue' ] == 'longitude' then -- долготы
return value[ 'longitude' ]
elseif options[ 'nocoord' ] and options[ 'nocoord' ] ~= '' then
-- если передан параметр nocoord, то не выводить координаты
-- обычно это делается при использовании нескольких карточек на странице
return ''
else
-- в противном случае формируются параметры для вызова шаблона {{coord}}
-- нужно дописать в документации шаблона, что он отсюда вызывается, и что
-- любое изменние его парамеров должно быть согласовано с кодом тут
local coordModule = require( 'Module:Coordinates' )
local globe = options.globe or ''
if globe == '' and value[ 'globe' ] then
local globes = require( 'Module:Wikidata/Globes' )
globe = globes[ value[ 'globe' ] ] or ''
end
local display = 'inline'
if options.display and options.display ~= '' then
display = options.display
elseif ( options.property:upper() == 'P625' ) then
display = 'title'
end
local format = options.format or ''
if format == '' then
format = 'dms'
if value[ 'precision' ] then
local precision = value[ 'precision' ] * 60
if precision >= 60 then
format = 'd'
elseif precision >= 1 then
format = 'dm'
end
end
end
g_frame.args = {
tostring( value[ 'latitude' ] ),
tostring( value[ 'longitude' ] ),
globe = globe,
type = options.type and options.type or '',
scale = options.scale and options.scale or '',
display = display,
format = format,
}
return coordModule.coord(g_frame)
end
end
---Функция для оформления объектов-значений с файлами с Викисклада
---@param value string Raw value.
---@param options table Parameters.
---@return string Formatted string.
local function formatCommonsMedia( value, options )
local image = value
local caption = ''
if options[ 'caption' ] and options[ 'caption' ] ~= '' then
caption = options[ 'caption' ]
end
if caption ~= '' then
caption = wrapQualifier( caption, 'P2096', { class = 'media-caption', style = 'display:block' } )
end
if not string.find( value, '[%[%]%{%}]' ) and not string.find( value, 'UNIQ%-%-imagemap' ) then
-- если в value не содержится викикод или imagemap, то викифицируем имя файла
-- ищем слово imagemap в строке, потому что вставляется плейсхолдер: [[phab:T28213]]
image = '[[File:' .. value .. '|frameless'
if options[ 'border' ] and options[ 'border' ] ~= '' then
image = image .. '|border'
end
local size = options[ 'size' ]
if size and size ~= '' then
-- TODO: check localized pixel names too
if not string.match( size, 'px$' ) then
size = size .. 'px'
end
else
size = fileDefaultSize
end
image = image .. '|' .. size
if options[ 'alt' ] and options[ 'alt' ] ~= '' then
image = image .. '|alt=' .. options[ 'alt' ]
end
if caption ~= '' then
image = image .. '|' .. caption
end
image = image .. ']]'
if caption ~= '' then
image = image .. '<br>' .. caption
end
else
image = image .. caption .. getCategoryByCode( 'media-contains-markup' )
end
return image
end
---Function for render math formulas
---@param value string Value.
---@param options table Parameters.
---@return string Formatted string.
local function formatMath( value, options )
return options.frame:extensionTag{ name = 'math', content = value }
end
---Функция для оформления внешних идентификаторов
---@param value string
---@param options table
---@return string
local function formatExternalId( value, options )
local formatter = options.formatter
local propertyId = options.property:upper()
if not formatter or formatter == '' then
local isGoodFormat = false
local wbStatus, formatRegexStatements = pcall( mw.wikibase.getBestStatements, propertyId, 'P1793' )
if wbStatus and formatRegexStatements then
for _, statement in pairs( formatRegexStatements ) do
if statement.mainsnak.snaktype == 'value' then
local pattern = mw.ustring.gsub( statement.mainsnak.datavalue.value, '\\', '%' )
pattern = mw.ustring.gsub( pattern, '{%d+,?%d*}', '+' )
if ( string.find( pattern, '|' ) or string.find( pattern, '%)%?' )
or mw.ustring.match( value, '^' .. pattern .. '$' ) ~= nil ) then
isGoodFormat = true
break
end
end
end
end
if isGoodFormat then
local formatterStatements
wbStatus, formatterStatements = pcall( mw.wikibase.getBestStatements, propertyId, 'P1630' )
if wbStatus and formatterStatements then
for _, statement in pairs( formatterStatements ) do
if statement.mainsnak.snaktype == 'value' then
formatter = statement.mainsnak.datavalue.value
break
end
end
end
end
end
if formatter and formatter ~= '' then
local encodedValue = mw.ustring.gsub( value, '%%', '%%%%' ) -- ломается, если подставить внутрь другого mw.ustring.gsub
local link = mw.ustring.gsub(
mw.ustring.gsub( formatter, '$1', encodedValue ), '.',
{ [ ' ' ] = '%20', [ '+' ] = '%2b', [ '[' ] = '%5B', [ ']' ] = '%5D' } )
local title = options.title
if not title or title == '' then
title = '$1'
end
title = mw.ustring.gsub(
mw.ustring.gsub( title, '$1', encodedValue ), '.',
{ [ '[' ] = '(', [ ']' ] = ')' } )
return '[' .. link .. ' ' .. title .. ']'
end
return value
end
---Функция для оформления числовых значений
---@param value table Объект-значение
---@param options table Таблица параметров
---@return string Оформленный текст
local function formatQuantity( value, options )
-- диапазон значений
local amount = string.gsub( value.amount, '^%+', '' )
local lang = mw.language.getContentLanguage()
local langCode = lang:getCode()
local function formatNum( number, sigfig )
local multiplier = ''
if options.countByThousands then
local powers = options.i18n.thousandPowers
local pos = 1
while math.abs( number ) >= 1000 and pos < #powers do
number = number / 1000
pos = pos + 1
end
multiplier = powers[ pos ]
if math.abs( number ) >= 100 then
sigfig = sigfig or 0
elseif math.abs( number ) >= 10 then
sigfig = sigfig or 1
else
sigfig = sigfig or 2
end
else
sigfig = sigfig or 12 -- округление до 12 знаков после запятой, на 13-м возникает ошибка в точности
end
local iMultiplier = 10^sigfig
number = math.floor( number * iMultiplier + 0.5 ) / iMultiplier
return string.gsub( lang:formatNum( number ), '^-', '−' ) .. multiplier
end
local out = formatNum( tonumber( amount ) )
if value.upperBound then
local diff = tonumber( value.upperBound ) - tonumber( amount )
if diff > 0 then -- временная провека, пока у большинства значений не будет убрано ±0
-- Пробуем понять до какого знака округлять
local integer, dot, decimals, _ = value.upperBound:match( '^+?-?(%d*)(%.?)(%d*)(.*)' )
local precision
if dot == '' then
precision = -integer:match( '0*$' ):len()
else
precision = #decimals
end
local bound = formatNum( diff, precision )
if string.match( bound, 'E%-(%d+)' ) then -- если в экспоненциальном формате
local digits = tonumber( string.match( bound, 'E%-(%d+)' ) ) - 2
bound = formatNum( diff * 10 ^ digits, precision )
bound = string.sub( bound, 0, 2 ) .. string.rep( '0', digits ) .. string.sub( bound, -string.len( bound ) + 2 )
end
out = out .. ' ± ' .. bound
end
end
if options.unit and options.unit ~= '' then
if options.unit ~= '-' then
out = out .. ' ' .. options.unit
end
elseif value.unit and string.match( value.unit, 'http://www.wikidata.org/entity/' ) then
local unitEntityId = string.gsub( value.unit, 'http://www.wikidata.org/entity/', '' )
if unitEntityId ~= 'undefined' then
local wbStatus, unitEntity = pcall( mw.wikibase.getEntity, unitEntityId )
if wbStatus == true and unitEntity then
if unitEntity.claims.P2370 and
unitEntity.claims.P2370[ 1 ].mainsnak.snaktype == 'value' and
not value.upperBound and
options.siConversion == true
then
local conversionToSiUnit = string.gsub( unitEntity.claims.P2370[ 1 ].mainsnak.datavalue.value.amount, '^%+', '' )
if math.floor( math.log10( conversionToSiUnit ) ) ~= math.log10( conversionToSiUnit ) then
-- Если не степени десятки (переводить сантиметры в метры не надо!)
local outValue = tonumber( amount ) * conversionToSiUnit
if outValue > 0 then
-- Пробуем понять до какого знака округлять
local integer, dot, decimals, _ = amount:match( '^(%d*)(%.?)(%d*)(.*)' )
local precision
if dot == '' then
precision = -integer:match( '0*$' ):len()
else
precision = #decimals
end
local adjust = math.log10( math.abs( conversionToSiUnit ) ) + math.log10( 2 )
local minPrecision = 1 - math.floor( math.log10( outValue ) + 2e-14 )
out = formatNum( outValue, math.max( math.floor( precision + adjust ), minPrecision ) )
else
out = formatNum( outValue, 0 )
end
unitEntityId = string.gsub( unitEntity.claims.P2370[ 1 ].mainsnak.datavalue.value.unit, 'http://www.wikidata.org/entity/', '' )
wbStatus, unitEntity = pcall( mw.wikibase.getEntity, unitEntityId )
end
end
local label = getLabelWithLang( context, options, unitEntity.id, nil, { "P5061", "P558", "P558" }, {
'P5061[language:' .. langCode .. ']',
'P558[P282:' .. writingSystemElementId .. ', P407:' .. langElementId .. ']',
'P558[!P282][!P407]'
} )
out = out .. ' ' .. label
end
end
end
return out
end
---Функция для оформления URL
---@param context table
---@param options table
---@param value string
local function formatUrlValue( context, options, value )
if not options.length or options.length == '' then
options.length = 25
end
local moduleUrl = require( 'Module:URL' )
return moduleUrl.formatUrlSingle( context, options, value )
end
local DATATYPE_CACHE = {}
---Get property datatype by ID.
---@param propertyId string Property ID, e.g. 'P123'.
---@return string Property datatype, e.g. 'commonsMedia', 'time' or 'url'.
local function getPropertyDatatype( propertyId )
if not propertyId or not string.match( propertyId, '^P%d+$' ) then
return nil
end
local cached = DATATYPE_CACHE[ propertyId ]
if cached ~= nil then
return cached
end
local wbStatus, propertyEntity = pcall( mw.wikibase.getEntity, propertyId )
if wbStatus ~= true or not propertyEntity then
return nil
end
mw.log("Loaded datatype " .. propertyEntity.datatype .. " of " .. propertyId .. ' from wikidata, consider passing datatype argument to formatProperty call or to Wikidata/config' )
DATATYPE_CACHE[ propertyId ] = propertyEntity.datatype
return propertyEntity.datatype
end
---@param datavalue table
---@return function
local function getPlainValueFunction( datavalue, _ )
if datavalue.type == 'wikibase-entityid' then
return function( _, _, value )
return getEntityIdFromValue( value )
end
elseif datavalue.type == 'string' then
return function( _, _, value )
return value
end
elseif datavalue.type == 'monolingualtext' then
return function( _, _, value )
return value.text
end
elseif datavalue.type == 'globecoordinate' then
return function( _, _, value )
return value.latitude .. ',' .. value.longitude
end
elseif datavalue.type == 'quantity' then
return function( _, _, value )
return value.amount
end
elseif datavalue.type == 'time' then
return function( _, _, value )
return value.time
end
end
throwError( 'unknown-datavalue-type' )
end
---@param datavalue table
---@param datatype string
---@return function
local function getDefaultValueFunction( datavalue, datatype )
-- вызов обработчиков по умолчанию для известных типов значений
if datavalue.type == 'wikibase-entityid' then
-- Entity ID
return function( context, options, value )
return formatEntityId( context, options, getEntityIdFromValue( value ) )
end
elseif datavalue.type == 'string' then
-- String
if datatype and datatype == 'commonsMedia' then
-- Media
return function( _, options, value )
return formatCommonsMedia( value, options )
end
elseif datatype and datatype == 'external-id' then
-- External ID
return function( _, options, value )
return formatExternalId( value, options )
end
elseif datatype and datatype == 'math' then
-- Math formula
return function( _, options, value )
return formatMath( value, options )
end
elseif datatype and datatype == 'url' then
-- URL
return formatUrlValue
end
return function( _, _, value )
return value
end
elseif datavalue.type == 'monolingualtext' then
-- моноязычный текст (строка с указанием языка)
return function( _, options, value )
if options.monolingualLangTemplate == 'lang' then
if value.language == CONTENT_LANGUAGE_CODE then
return value.text
end
return options.frame:expandTemplate{ title = 'lang-' .. value.language, args = { value.text } }
elseif options.monolingualLangTemplate == 'ref' then
return '<span class="lang" lang="' .. value.language .. '">' .. value.text .. '</span>' .. options.frame:expandTemplate{ title = 'ref-' .. value.language }
else
return '<span class="lang" lang="' .. value.language .. '">' .. value.text .. '</span>'
end
end
elseif datavalue.type == 'globecoordinate' then
-- географические координаты
return function( _, options, value )
return formatGlobeCoordinate( value, options )
end
elseif datavalue.type == 'quantity' then
return function( _, options, value )
return formatQuantity( value, options )
end
elseif datavalue.type == 'time' then
return function( context, options, value )
local moduleDate = require( 'Module:Wikidata/date' )
return moduleDate.formatDate( context, options, value )
end
end
-- во всех стальных случаях возвращаем ошибку
throwError( 'unknown-datavalue-type' )
end
---Функция для оформления значений (value)
---Подробнее о значениях см. d:Wikidata:Glossary/ru
---@param context table
---@param options table
---@param datavalue table
---@param datatype string
---@return string Оформленный текст
function formatDatavalue( context, options, datavalue, datatype )
if not context then error( 'context not specified' ); end
if not options then error( 'options not specified' ); end
if not datavalue then error( 'datavalue not specified' ); end
if not datavalue.value then error( 'datavalue.value is missing' ); end
-- проверка на указание специализированных обработчиков в параметрах,
-- переданных при вызове
if options.plain then
context.formatValueDefault = getPlainValueFunction( datavalue, datatype )
else
context.formatValueDefault = getDefaultValueFunction( datavalue, datatype )
end
local functionToCall = getUserFunction( options, 'value', context.formatValueDefault )
return functionToCall( context, options, datavalue.value )
end
local DEFAULT_BOUNDARIES = { os.time() * 1000, os.time() * 1000}
---Функция для оформления идентификатора сущности
---@param context table
---@param options table
---@param entityId string
---@return string Оформленный текст
function formatEntityId( context, options, entityId )
-- получение локализованного названия
local boundaries
if options.qualifiers then
boundaries = p.getTimeBoundariesFromQualifiers( context.frame, context, { qualifiers = options.qualifiers } )
end
if not boundaries then
boundaries = DEFAULT_BOUNDARIES
end
local label, labelLanguageCode = getLabelWithLang( context, options, entityId, boundaries )
-- определение соответствующей показываемому элементу категории
local category = context.extractCategory( options, { id = entityId } )
-- получение ссылки по идентификатору
local link = mw.wikibase.sitelink( entityId )
if link then
-- ссылка на категорию, а не добавление страницы в неё
if mw.ustring.match( link, '^' .. mw.site.namespaces[ 14 ].name .. ':' ) then
link = ':' .. link
end
if label and not options.rawArticle then
if labelLanguageCode ~= CONTENT_LANGUAGE_CODE then
label = '<span lang="' .. label .. '">' .. label .. '</span>'
end
local a = '[[' .. link .. '|' .. label .. ']]'
if CONTENT_LANGUAGE_CODE ~= labelLanguageCode and 'mul' ~= labelLanguageCode then
a = a .. getCategoryByCode( 'links-to-entities-with-missing-local-language-label' )
end
return a .. category
else
return '[[' .. link .. ']]' .. category
end
end
if label then -- TODO: возможно, лучше просто mw.wikibase.getLabel(entityId)
-- красная ссылка
-- TODO: разобраться, почему не всегда есть options.frame
local moduleRedLink = require( 'Module:Wikidata/redLink' )
local title = mw.title.new( label )
if title and not title.exists and options.frame then
local rawLabel = mw.wikibase.getLabel(entityId) or label -- без |text= и boundaries; or label - костыль
local redLink = moduleRedLink.formatRedLinkWithInfobox(rawLabel, label, entityId)
if CONTENT_LANGUAGE_CODE ~= labelLanguageCode and 'mul' ~= labelLanguageCode then
redLink = '<span lang="' .. labelLanguageCode .. '">' .. redLink .. '</span>' ..
getCategoryByCode( 'links-to-entities-with-missing-local-language-label' )
end
return redLink .. category
end
-- TODO: перенести до проверки на существование статьи
local addWdLink = false
if ( not options.format or options.format ~= 'text' )
and entityId ~= 'Q6581072' and entityId ~= 'Q6581097' -- TODO: переписать на format=text
then
addWdLink = true
end
-- одноимённая статья уже существует - выводится текст и ссылка на ВД
return moduleRedLink.formatText(label, entityId, addWdLink) .. category
end
-- сообщение об отсутвии локализованного названия
-- not good, but better than nothing
return '[[:d:' .. entityId .. '|' .. entityId .. ']]<span style="border-bottom: 1px dotted; cursor: help; white-space: nowrap" title="В Викиданных нет русской подписи к элементу. Вы можете помочь, указав русский вариант подписи.">?</span>' .. getCategoryByCode( 'links-to-entities-with-missing-label' ) .. category
end
---Функция для оформления утверждений (statement)
---Подробнее о утверждениях см. d:Wikidata:Glossary/ru
---@deprecated Use p.formatProperty() instead
---@param frame table
---@return string Строка оформленного текста, предназначенная для отображения в статье
function p.formatStatements( frame )
return p.formatProperty( frame )
end
---Получение параметров, которые обычно используются для вывода свойства.
---@param propertyId string
---@param datatype string
---@param params table
function getPropertyParams( propertyId, datatype, params )
local config = getConfig()
-- Различные уровни настройки параметров, по убыванию приоритета
local propertyParams = {}
-- 1. Параметры, указанные явно при вызове
if params then
for key, value in pairs( params ) do
if value ~= '' then
propertyParams[ key ] = value
end
end
end
if toBoolean( propertyParams.plain, false ) then
propertyParams.separator = propertyParams.separator or ', '
propertyParams.conjunction = propertyParams.conjunction or ', '
else
-- 2. Настройки конкретного параметра
if config.properties and config.properties[ propertyId ] then
for key, value in pairs( config.properties[ propertyId ] ) do
if propertyParams[ key ] == nil then
propertyParams[ key ] = value
end
end
end
-- 3. Указанный пресет настроек
if propertyParams.preset and config.presets and
config.presets[ propertyParams.preset ]
then
for key, value in pairs( config.presets[ propertyParams.preset ] ) do
if propertyParams[ key ] == nil then
propertyParams[ key ] = value
end
end
end
datatype = datatype or params.datatype or propertyParams.datatype or getPropertyDatatype( propertyId )
if propertyParams.datatype == nil then
propertyParams.datatype = datatype
end
-- 4. Настройки для типа данных
if datatype and config.datatypes and config.datatypes[ datatype ] then
for key, value in pairs( config.datatypes[ datatype ] ) do
if propertyParams[ key ] == nil then
propertyParams[ key ] = value
end
end
end
-- 5. Общие настройки для всех свойств
if config.global then
for key, value in pairs( config.global ) do
if propertyParams[ key ] == nil then
propertyParams[ key ] = value
end
end
end
end
return propertyParams
end
---Функция для оформления утверждений (statement)
---Подробнее о утверждениях см. d:Wikidata:Glossary/ru
---@param frame table
---@return string Строка оформленного текста, предназначенная для отображения в статье
function p.formatProperty( frame )
local args = copyTo( frame.args, {} )
-- проверка на отсутствие обязательного параметра property
if not args.property then
throwError( 'property-param-not-provided' )
end
local override
local propertyId = mw.language.getContentLanguage():ucfirst( string.gsub( args.property, '([^Pp0-9].*)$', function(w)
if string.sub( w, 1, 1 ) == '~' then
override = w
end
return ''
end ) )
if override then
args[ override:match( '[,~]([^=]*)=' ) ] = override:match( '=(.*)' )
args.property = propertyId
end
-- проброс всех параметров из шаблона {wikidata} и параметра from откуда угодно
local p_frame = frame
while p_frame do
if p_frame:getTitle() == mw.site.namespaces[ 10 ].name .. ':Wikidata' then
copyTo( p_frame.args, args, true )
end
if p_frame.args and p_frame.args.from and p_frame.args.from ~= '' then
args.entityId = p_frame.args.from
else
args.entityId = mw.wikibase.getEntityIdForCurrentPage()
end
p_frame = p_frame:getParent()
end
args = getPropertyParams( propertyId, nil, args )
local datatype = args.datatype
-- перевод итоговых значений флагов в true/false и добавление значений
-- по умолчанию только в том случае, если они нигде не были указаны ранее
args.plain = toBoolean( args.plain, false )
args.nocat = not args.plain and toBoolean( args.nocat, false )
args.references = not args.plain and toBoolean( args.references, true )
-- если значение передано в параметрах вызова то выводим только его
if args.value and args.value ~= '' then
-- специальное значение для скрытия Викиданных
if args.value == '-' then
return ''
end
local value = args.value
-- опция, запрещающая оформление значения, поэтому никак не трогаем
if args.plain then
return value
end
local context = initContext( args )
-- обработчики по типу значения
local wrapperExtraArgs = {}
if args[ 'value-module' ] and args[ 'value-function' ] and not string.find( value, '[%[%]%{%}]' ) then
local func = getUserFunction( args, 'value' )
value = func( context, args, value )
elseif datatype == 'commonsMedia' then
value = formatCommonsMedia( value, args )
elseif datatype == 'external-id' and not string.find( value, '[%[%]%{%}]' ) then
wrapperExtraArgs[ 'data-wikidata-external-id' ] = mw.text.killMarkers( value )
value = formatExternalId( value, args )
--elseif datatype == 'math' then
-- args.frame = frame -- костыль: в formatMath нужно frame:extensionTag
-- value = formatMath( value, args )
elseif datatype == 'url' then
value = formatUrlValue( context, args, value )
end
-- оборачиваем в тег для JS-функций
if string.match( propertyId, '^P%d+$' ) then
value = mw.text.trim( value )
-- временная штрафная категория для исправления табличных вставок
local allowTables = getPropertyParams( propertyId, nil, {} ).allowTables
if not allowTables
and string.match( value, '<t[dhr][ >]' )
-- and not string.match( value, '<table[ >]' )
-- and not string.match( value, '^%{%|' )
then
value = value .. getCategoryByCode( 'value-contains-table', propertyId )
else
value = wrapStatement( value, propertyId, nil, wrapperExtraArgs )
end
end
return value
end
-- ability to disable loading Wikidata
if args.entityId == '-' then
return ''
end
g_frame = frame
-- после проверки всех аргументов -- вызов функции оформления для свойства (набора утверждений)
return formatProperty( args )
end
---Функция проверки на присутствие источника в списке нерекомендованных.
---@param snaks table
---@return boolean
local function isReferenceDeprecated( snaks )
if not snaks then
return false
end
if snaks.P248
and snaks.P248[ 1 ]
and snaks.P248[ 1 ].datavalue
and snaks.P248[ 1 ].datavalue.value.id
then
local entityId = snaks.P248[ 1 ].datavalue.value.id
if getConfig( 'deprecatedSources', entityId ) then
return true
end
elseif snaks.P1433
and snaks.P1433[ 1 ]
and snaks.P1433[ 1 ].datavalue
and snaks.P1433[ 1 ].datavalue.value.id
then
local entityId = snaks.P1433[ 1 ].datavalue.value.id
if getConfig( 'deprecatedSources', entityId ) then
return true
end
end
return false
end
---Функция оформления ссылок на источники (reference)
---Подробнее о ссылках на источники см. d:Wikidata:Glossary/ru
---
---Экспортируется в качестве зарезервированной точки для вызова из функций-расширения вида claim-module/claim-function через context
---Вызов из других модулей напрямую осуществляться не должен (используйте frame:expandTemplate вместе с одним из специлизированных шаблонов вывода значения свойства).
---@param context table
---@param options table
---@param statement table
---@return string Оформленные примечания для отображения в статье
function formatRefs( context, options, statement )
if not context then error( 'context not specified' ); end
if not options then error( 'options not specified' ); end
if not options.entityId then error( 'options.entityId missing' ); end
if not statement then error( 'statement not specified' ); end
if not outputReferences then
return ''
end
---@type string[]
local references = {}
if statement.references then
local hasNotDeprecated = false
local displayCount = 0
for _, reference in pairs( statement.references ) do
if not isReferenceDeprecated( reference.snaks ) then
hasNotDeprecated = true
end
end
for _, reference in pairs( statement.references ) do
local display = true
if hasNotDeprecated then
if isReferenceDeprecated( reference.snaks ) then
display = false
end
end
if displayCount >= 2 then
if options.entityId and options.property then
local propertyId = mw.ustring.match( options.property, '^[Pp][0-9]+' ) -- TODO: обрабатывать не тут, а раньше
local moreReferences = '<sup>[[d:' .. options.entityId .. '#' .. string.upper( propertyId ) .. '|[…]]]</sup>'
table.insert( references, moreReferences )
end
break
end
if display == true then
---@type string
local refText = moduleSources.renderReference( g_frame, options.entityId, reference )
if refText and refText ~= '' then
table.insert( references, refText )
displayCount = displayCount + 1
end
end
end
end
return table.concat( references )
end
return p
4558f762f30c6ebfb9f5333dbd7ebda83c6873f2
Заглавная страница
0
1
1
2024-08-07T16:07:23Z
MediaWiki default
1
Добро пожаловать в Miraheze!
wikitext
text/x-wiki
__NOTOC__
== Добро пожаловать в {{SITENAME}}! ==
Эта главная страница была создана автоматически и, похоже, ещё не заменена.
=== Для бюрократа(-ов) этой вики ===
Здравствуйте и добро пожаловать на вашу новую вики! Благодарим Вас за выбор Miraheze в качестве хостинга, и мы надеемся, что вы будете пользоваться нашими услугами.
Вы можете сразу же начать работать над вашем вики-сайтов, как только пожелаете.
Нужна помощь? Нет проблем! Мы поможем вам с вашей вики по мере необходимости. Для того, чтобы начать, мы добавили несколько ссылок о работе с MediaWiki:
* [[mw:Special:MyLanguage/Help:Contents|Обсуждение руководства MediaWiki (например, навигация, редактирование, удаление страниц, блокирование пользователей)]]
* [[meta:Special:MyLanguage/FAQ|ЧЗВ по Miraheze]]
* [[meta:Special:MyLanguage/Request features|Запрос изменений настроек вашей вики.]] (Изменения расширений, оформления и логотипа/фавикона должны выполняться через [[Special:ManageWiki]] в вашей вики, см. [[meta:Special:MyLanguage/ManageWiki|ManageWiki]] для получения дополнительной информации.)
==== Но, Miraheze, я всё ещё не понимаю X! ====
Что ж, это не проблема. Даже если что-то не описано в документации/ЧЗВ, мы всё равно будем рады помочь вам. Вы можете найти нас здесь:
* [[meta:Special:MyLanguage/Help center|На нашем собственном Miraheze вики]]
* На [[phorge:|Phorge]]
* На нашем [https://miraheze.org/discord Discord-сервере]
* На IRC в #miraheze в irc.libera.chat (irc.libera.chat ([irc://irc.libera.chat/%23miraheze direct link]; [https://web.libera.chat/?channel=#miraheze вебчат]))
=== Для посетителя этой вики ===
Здравствуйте, заглавная страница по умолчанию ещё не была заменена бюрократом(-ами) этой вики. Возможно, администрация этого сайта разрабатывает эту страницу, поэтому мы рекомендуем вам зайти чуть позже.
da708791005da529f6c1fffe139a9b3660d023e2
12
1
2024-08-07T17:48:49Z
DuOfOrl
5
Защитил страницу [[Заглавная страница]]: популярная страница ([Редактирование=Разрешено только администраторам] (бессрочно) [Переименование=Разрешено только администраторам] (бессрочно))
wikitext
text/x-wiki
__NOTOC__
== Добро пожаловать в {{SITENAME}}! ==
Эта главная страница была создана автоматически и, похоже, ещё не заменена.
=== Для бюрократа(-ов) этой вики ===
Здравствуйте и добро пожаловать на вашу новую вики! Благодарим Вас за выбор Miraheze в качестве хостинга, и мы надеемся, что вы будете пользоваться нашими услугами.
Вы можете сразу же начать работать над вашем вики-сайтов, как только пожелаете.
Нужна помощь? Нет проблем! Мы поможем вам с вашей вики по мере необходимости. Для того, чтобы начать, мы добавили несколько ссылок о работе с MediaWiki:
* [[mw:Special:MyLanguage/Help:Contents|Обсуждение руководства MediaWiki (например, навигация, редактирование, удаление страниц, блокирование пользователей)]]
* [[meta:Special:MyLanguage/FAQ|ЧЗВ по Miraheze]]
* [[meta:Special:MyLanguage/Request features|Запрос изменений настроек вашей вики.]] (Изменения расширений, оформления и логотипа/фавикона должны выполняться через [[Special:ManageWiki]] в вашей вики, см. [[meta:Special:MyLanguage/ManageWiki|ManageWiki]] для получения дополнительной информации.)
==== Но, Miraheze, я всё ещё не понимаю X! ====
Что ж, это не проблема. Даже если что-то не описано в документации/ЧЗВ, мы всё равно будем рады помочь вам. Вы можете найти нас здесь:
* [[meta:Special:MyLanguage/Help center|На нашем собственном Miraheze вики]]
* На [[phorge:|Phorge]]
* На нашем [https://miraheze.org/discord Discord-сервере]
* На IRC в #miraheze в irc.libera.chat (irc.libera.chat ([irc://irc.libera.chat/%23miraheze direct link]; [https://web.libera.chat/?channel=#miraheze вебчат]))
=== Для посетителя этой вики ===
Здравствуйте, заглавная страница по умолчанию ещё не была заменена бюрократом(-ами) этой вики. Возможно, администрация этого сайта разрабатывает эту страницу, поэтому мы рекомендуем вам зайти чуть позже.
da708791005da529f6c1fffe139a9b3660d023e2
24
12
2024-08-07T19:38:25Z
DuOfOrl
5
Содержимое страницы заменено на «__NOTOC__ == Добро пожаловать в Мемнотацию! == {{Заглавная/Шапка}}»
wikitext
text/x-wiki
__NOTOC__
== Добро пожаловать в Мемнотацию! ==
{{Заглавная/Шапка}}
a8912afb15aae163f13fdf2d00a073d790456b46
Участник:DuOfOrl
2
2
2
2024-08-07T16:51:15Z
DuOfOrl
5
Новая страница: «MC Гей да нет да нет (играет гимн Ксеноморфии на электрооргане)»
wikitext
text/x-wiki
MC Гей да нет да нет (играет гимн Ксеноморфии на электрооргане)
18e6c33c25c1077c6d40bf450350c8e5182fbd4f
Участник:Ксеноморф
2
3
3
2024-08-07T16:52:28Z
Ксеноморф
2
Новая страница: «Ну тип создатель этого эээ да уничтожим всех врагов Ксеноморфии слава Ксеноморфии»
wikitext
text/x-wiki
Ну тип создатель этого эээ да уничтожим всех врагов Ксеноморфии слава Ксеноморфии
ac12e2fdee9713b6f2586c714ef7bd4d1f4a6234
4
3
2024-08-07T16:52:42Z
Ксеноморф
2
wikitext
text/x-wiki
Ну тип создатель этого вики эээ да уничтожим всех врагов Ксеноморфии слава Ксеноморфии
3c284ed9ea37e4df70fa0c998db3597e7fce87cb
Файл:MemnotationLogo.png
6
5
6
2024-08-07T17:28:38Z
Ксеноморф
2
Сделан Афонтовианом
wikitext
text/x-wiki
== Краткое описание ==
Сделан Афонтовианом
063760b12b36ca743f38b960e8ce615c9f77b07e
7
6
2024-08-07T17:38:41Z
Ксеноморф
2
Ксеноморф загрузил новую версию [[Файл:MemnotationLogo.png]]
wikitext
text/x-wiki
== Краткое описание ==
Сделан Афонтовианом
063760b12b36ca743f38b960e8ce615c9f77b07e
8
7
2024-08-07T17:39:30Z
Ксеноморф
2
Ксеноморф загрузил новую версию [[Файл:MemnotationLogo.png]]
wikitext
text/x-wiki
== Краткое описание ==
Сделан Афонтовианом
063760b12b36ca743f38b960e8ce615c9f77b07e
9
8
2024-08-07T17:40:16Z
Ксеноморф
2
Ксеноморф загрузил новую версию [[Файл:MemnotationLogo.png]]
wikitext
text/x-wiki
== Краткое описание ==
Сделан Афонтовианом
063760b12b36ca743f38b960e8ce615c9f77b07e
10
9
2024-08-07T17:41:56Z
Ксеноморф
2
Ксеноморф загрузил новую версию [[Файл:MemnotationLogo.png]]
wikitext
text/x-wiki
== Краткое описание ==
Сделан Афонтовианом
063760b12b36ca743f38b960e8ce615c9f77b07e
11
10
2024-08-07T17:44:34Z
Ксеноморф
2
Ксеноморф загрузил новую версию [[Файл:MemnotationLogo.png]]
wikitext
text/x-wiki
== Краткое описание ==
Сделан Афонтовианом
063760b12b36ca743f38b960e8ce615c9f77b07e
Шаблон:Заглавная/Шапка
10
6
14
13
2024-08-07T18:17:06Z
DuOfOrl
5
1 версия импортирована: Экспортировано из Русской Википедии (https://ru.wikipedia.org/wiki/%D0%A8%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD:%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F/%D0%A8%D0%B0%D0%BF%D0%BA%D0%B0)
wikitext
text/x-wiki
<noinclude><templatestyles src="Шаблон:Заглавная/styles.css" /></noinclude>
<templatestyles src="Шаблон:Заглавная/Шапка/styles.css" />
<div class="main-block main-top">
<div class="main-top-left">
<h1 class="main-top-header">Добро пожаловать в [[Википедия|Википедию]],</h1>
[[Свободный контент|свободную энциклопедию]], которую [[Справка:Введение в Википедию|может редактировать каждый]].
<div class="main-top-mobileSearch"><span class="main-top-mobileSearchButton skin-minerva-search-trigger">[[Special:Search|Искать среди {{NUMBEROFARTICLES}} {{plural:{{NUMBEROFARTICLES}}|статьи|статей}}]]</span></div>
</div>
<div class="main-top-right main-plainlist">
<p class="main-top-articleCount">Сейчас в Википедии '''[[Special:Statistics|{{NUMBEROFARTICLES}} {{plural:{{NUMBEROFARTICLES}}|статья|статьи|статей}}]]''' на [[Русский язык|русском языке]].</p>
<ul>
<li class="main-top-createArticle">{{Заглавная/Кнопка|Википедия:Мастер статей|Создать статью}}</li>
<li>{{Заглавная/Кнопка|Википедия:Справка|Справка|class=mw-ui-quiet}}</li>
<li>{{Заглавная/Кнопка|Портал:Обзор|Порталы|class=mw-ui-quiet}}</li>
</ul>
</div>
</div><noinclude>
[[Категория:Шаблоны:Подстраницы шаблонов|Заглавная]]
[[Категория:Шаблоны, используемые на Заглавной странице]]
</noinclude>
824063451cf8a6bfd68477221e98b721c54adfe9
23
14
2024-08-07T19:36:43Z
DuOfOrl
5
wikitext
text/x-wiki
<noinclude><templatestyles src="Шаблон:Заглавная/styles.css" /></noinclude>
<templatestyles src="Шаблон:Заглавная/Шапка/styles.css" />
<div class="main-block main-top">
<h1 class="main-top-header"> [[Файл:MemnotationLogo.png]]</h1>
<div class="main-top-left">
<h1 class="main-top-header">Добро пожаловать в [[Мемнотация|Мемнотацию]],</h1>
свободную энциклопедию, затрагивающую тему Мемного мира, дискорд-государств и прочего.
<div class="main-top-mobileSearch"><span class="main-top-mobileSearchButton skin-minerva-search-trigger">[[Special:Search|Искать среди {{NUMBEROFARTICLES}} {{plural:{{NUMBEROFARTICLES}}|статьи|статей}}]]</span></div>
</div>
<div class="main-top-right main-plainlist">
<p class="main-top-articleCount">Сейчас в Мемнотации '''[[Special:Statistics|{{NUMBEROFARTICLES}} {{plural:{{NUMBEROFARTICLES}}|статья|статьи|статей}}]]'''.</p>
</div><noinclude>
[[Категория:Шаблоны:Подстраницы шаблонов|Заглавная]]
[[Категория:Шаблоны, используемые на Заглавной странице]]
</noinclude>
ff19767d497e881c8d6f34f43e14ed773a5597da
Шаблон:Заглавная/styles.css
10
8
19
18
2024-08-07T18:23:17Z
DuOfOrl
5
1 версия импортирована: Экспортировано из Русской Википедии
sanitized-css
text/css
/*
Новое оформление [[Заглавная страница]]
Главный референс:
https://design.wikimedia.org/style-guide/
https://github.com/wikimedia/wikimedia-ui-base/blob/master/wikimedia-ui-base.less
Не удаляйте код до завершения работы
*/
/* Стандартные заголовки */
.main-header.main-header.main-header {
border-bottom-color: transparent;
margin-bottom: 0.25em;
margin-top: 0;
padding-bottom: 0;
padding-top: 0;
}
body.skin-minerva .main-block h1,
body.skin-minerva .main-block h2 {
/* хак для Минервы в связи с [[mw:Heading HTML changes]] */
display: block;
}
body.skin-timeless .main-header.main-header.main-header {
border-bottom-color: transparent;
}
/* Списки без оформления */
.main-plainlist ul {
list-style: none;
margin: 0;
padding: 0;
}
.main-plainlist li {
margin-bottom: 0;
}
/* Убираем нумерацию заголовков, создаваемую опцией «Автоматически нумеровать заголовки»
на [[Служебная:Настройки#mw-prefsection-rendering]] */
.main-block .mw-headline-number {
display: none;
}
/* Скопировано из [[:w:Template:Screen reader-only/styles.css]] */
.main-block .sr-only {
border: 0;
clip: rect(0, 0, 0, 0); /* Removed from CSS specification */
/* clip-path is the replacement for clip, but very few browsers support it. */
clip-path: polygon(0px 0px, 0px 0px, 0px 0px);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
white-space: nowrap;
}
/*
Планшеты
*/
@media (min-width: 720px) {
.main-wikimedia {
padding-left: 1rem;
padding-right: 1rem;
}
}
/*
Стационарные компьютеры
*/
@media (min-width: 1000px) {
.main-wrapper {
display: flex;
gap: 1.5rem;
/* Fixes https://phabricator.wikimedia.org/F54943102 */
flex-wrap: wrap;
}
.main-wrapper-column {
flex: 1;
}
.main-wikimedia {
padding-left: 1.5rem;
padding-right: 1.5rem;
}
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
22963811044f787be151a02e4e09cbdc96d990d3
21
19
2024-08-07T19:18:12Z
DuOfOrl
5
sanitized-css
text/css
/*
Новое оформление [[Заглавная страница]]
Главный референс:
https://design.wikimedia.org/style-guide/
https://github.com/wikimedia/wikimedia-ui-base/blob/master/wikimedia-ui-base.less
Не удаляйте код до завершения работы
*/
/* Стандартные заголовки */
.main-header.main-header.main-header {
border-bottom-color: transparent;
margin-bottom: 0.25em;
margin-top: 0;
padding-bottom: 0;
padding-top: 0;
}
body.skin-timeless .main-header.main-header.main-header {
border-bottom-color: transparent;
}
/* Списки без оформления */
.main-plainlist > ul {
list-style: none;
margin: 0;
padding: 0;
}
.main-plainlist li {
margin-bottom: 0;
}
/* Убираем нумерацию заголовков, создаваемую опцией «Автоматически нумеровать заголовки»
на [[Служебная:Настройки#mw-prefsection-rendering]] */
.main-block .mw-headline-number {
display: none;
}
/* Скопировано из [[:w:Template:Screen reader-only/styles.css]] */
.main-block .sr-only {
border: 0;
clip: rect(0, 0, 0, 0); /* Removed from CSS specification */
/* clip-path is the replacement for clip, but very few browsers support it. */
clip-path: polygon(0px 0px, 0px 0px, 0px 0px);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
white-space: nowrap;
}
/*
Планшеты
*/
@media (min-width: 720px) {
.main-wikimedia {
padding-top: 1rem;
padding-left: 1rem;
padding-right: 1rem;
}
}
/*
Стационарные компьютеры
*/
@media (min-width: 1000px) {
.main-wrapper {
display: flex;
margin: 0 -0.75rem;
}
.main-wrapper-column {
flex: 1;
margin: 0 0.75rem;
}
.main-wikimedia {
padding-top: 1.5rem;
padding-left: 1.5rem;
padding-right: 1.5rem;
}
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
d9380aba4391612dd1da0942c05b2d2808b0d483
Шаблон:Заглавная/Шапка/styles.css
10
9
20
2024-08-07T18:24:16Z
DuOfOrl
5
Новая страница: «/* Новое оформление [[Заглавная страница]] Главный референс: https://design.wikimedia.org/style-guide/ https://github.com/wikimedia/wikimedia-ui-base/blob/master/wikimedia-ui-base.less Не удаляйте код до завершения работы */ /* Стандартные заголовки */ .main-header.main-header.main-header { border-bottom-color: transparent; margin-bottom: 0.25em; margin-to...»
sanitized-css
text/css
/*
Новое оформление [[Заглавная страница]]
Главный референс:
https://design.wikimedia.org/style-guide/
https://github.com/wikimedia/wikimedia-ui-base/blob/master/wikimedia-ui-base.less
Не удаляйте код до завершения работы
*/
/* Стандартные заголовки */
.main-header.main-header.main-header {
border-bottom-color: transparent;
margin-bottom: 0.25em;
margin-top: 0;
padding-bottom: 0;
padding-top: 0;
}
body.skin-minerva .main-block h1,
body.skin-minerva .main-block h2 {
/* хак для Минервы в связи с [[mw:Heading HTML changes]] */
display: block;
}
body.skin-timeless .main-header.main-header.main-header {
border-bottom-color: transparent;
}
/* Списки без оформления */
.main-plainlist ul {
list-style: none;
margin: 0;
padding: 0;
}
.main-plainlist li {
margin-bottom: 0;
}
/* Убираем нумерацию заголовков, создаваемую опцией «Автоматически нумеровать заголовки»
на [[Служебная:Настройки#mw-prefsection-rendering]] */
.main-block .mw-headline-number {
display: none;
}
/* Скопировано из [[:w:Template:Screen reader-only/styles.css]] */
.main-block .sr-only {
border: 0;
clip: rect(0, 0, 0, 0); /* Removed from CSS specification */
/* clip-path is the replacement for clip, but very few browsers support it. */
clip-path: polygon(0px 0px, 0px 0px, 0px 0px);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
white-space: nowrap;
}
/*
Планшеты
*/
@media (min-width: 720px) {
.main-wikimedia {
padding-left: 1rem;
padding-right: 1rem;
}
}
/*
Стационарные компьютеры
*/
@media (min-width: 1000px) {
.main-wrapper {
display: flex;
gap: 1.5rem;
/* Fixes https://phabricator.wikimedia.org/F54943102 */
flex-wrap: wrap;
}
.main-wrapper-column {
flex: 1;
}
.main-wikimedia {
padding-left: 1.5rem;
padding-right: 1.5rem;
}
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
22963811044f787be151a02e4e09cbdc96d990d3
22
20
2024-08-07T19:34:29Z
DuOfOrl
5
sanitized-css
text/css
/*
Новое оформление шаблона [[Шаблон:Заглавная/Шапка]]
Основано на:
https://github.com/wikimedia/wikimedia-ui-base/blob/master/wikimedia-ui-base.less
https://design.wikimedia.org/style-guide/
*/
.main-top {
clear: both;
margin-top: 1rem;
padding-bottom: 1.5rem;
}
.main-top-left {
font-size: 1rem;
}
.main-top-left > p {
font-size: 0.875em;
margin: 0.5em 0 0;
padding: 0;
}
body.skin-vector .main-top-left > p,
body.skin-minerva .main-top-left > p,
body.skin-timeless .main-top-left > p {
margin: 0;
}
.main-top-right {
margin-top: 0.5em;
}
.main-top-right > ul {
display: none;
margin-top: 0.5rem;
}
.main-top-header {
border-bottom: 0;
margin: 0;
padding: 0;
}
body.skin-monobook .main-top-header {
line-height: 1;
}
.main-top-articleCount {
margin: 0;
padding: 0;
}
body.skin-minerva .main-top-articleCount {
display: none;
}
.main-top-mobileSearch {
display: none;
margin-top: 1rem;
}
body.skin-minerva .main-top-mobileSearch {
display: block;
}
body.skin-minerva .main-top-mobileSearch .main-top-mobileSearchButton a {
background: #fff;
border: none;
box-shadow: 0 2px 2px 0 rgba( 0, 0, 0, 0.25 );
color: #72777d;
display: block;
font-weight: normal;
padding: 0.25em 0.85em;
text-decoration: none;
text-align: left;
}
/*
Планшеты
*/
@media (min-width: 720px) {
.main-top {
background-color: #f8f9fa;
border: 1px solid #c8ccd1;
border-radius: 2px;
box-shadow: 0 1px 1px rgba(0, 0, 0, .15);
margin-bottom: 1rem;
padding: 1rem;
}
.main-top-right > ul {
display: flex;
flex-wrap: wrap;
}
.main-top-articleCount {
margin-bottom: 0.5rem;
}
body.skin-minerva .main-top-articleCount {
display: block;
}
body.skin-minerva .main-top-mobileSearch {
display: none;
}
}
/*
Стационарные компьютеры
*/
@media (min-width: 1000px) {
.main-top {
align-items: center;
background-image: url(https://upload.wikimedia.org/wikipedia/commons/e/e3/Wikipedia_logo_letters_banner.svg);
background-position: right;
background-repeat: no-repeat;
display: flex;
margin-bottom: 1.5rem;
margin-top: 0.5rem;
padding-bottom: 0;
padding-left: 0;
padding-top: 0;
}
.main-top-left {
background-image: linear-gradient(to right, #f8f9fa 0%, #f8f9fa 70%, rgba(248, 249, 250, 0) 100%);
flex: 2.5;
padding: 2rem 0 2rem 1rem;
}
.main-top-right {
flex: 2;
margin-top: 0;
text-align: right;
}
.main-top-right > ul {
align-items: center;
flex-direction: row-reverse;
gap: 0.5em;
justify-content: right;
margin-top: 0;
text-align: left;
}
}
/*
Широкие стационарные компьютеры
*/
@media (min-width: 1280px) {
.main-top {
padding-right: 1.5rem;
}
body.skin-minerva .main-top,
body.skin-vector-2022 .main-top {
padding-right: 1rem;
}
.main-top-left {
padding-left: 1.5rem;
}
body.skin-minerva .main-top-left,
body.skin-vector-2022 .main-top-left {
padding-left: 1rem;
}
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
d58309b538c16843c1518ff7efa497f562e036ea
Шаблон:Документировать
10
18
36
2024-08-08T15:54:53Z
DuOfOrl
5
Новая страница: «{{ombox |type = content |text = '''Этому {{#ifeq: {{NAMESPACE}} | Модуль | модулю | шаблону }} не хватает [[Проект:Технические работы/Шаблоны/Документирование|документации]].''' |text-small = Вы можете помочь проекту, {{big|'''{{SUBJECTSPACE}}:{{PAGENAME:{{{1|{{SUBJECTPAGENAME}}/doc}}}}}|создав описание {{#ifeq: {{NAMESP...»
wikitext
text/x-wiki
{{ombox
|type = content
|text = '''Этому {{#ifeq: {{NAMESPACE}} | Модуль | модулю | шаблону }} не хватает [[Проект:Технические работы/Шаблоны/Документирование|документации]].'''
|text-small = Вы можете помочь проекту, {{big|'''[[{{SUBJECTSPACE}}:{{PAGENAME:{{{1|{{SUBJECTPAGENAME}}/doc}}}}}|создав описание {{#ifeq: {{NAMESPACE}} | Модуль | модуля | шаблона }}]]'''}}: что он делает, как его использовать, какие параметры он принимает, в какие категории добавляет. Это поможет другим использовать его.
* Не забывайте про [[Проект:Технические работы/Шаблоны/Категоризация|категории]] ({{#ifeq: {{NAMESPACE}} | Модуль || на странице /doc  }}их нужно оборачивать в {{tag|includeonly}}) и интервики.
* Некоторые советы по оформлению есть на странице проекта «[[Проект:Технические работы/Шаблоны/Документирование|Документирование шаблонов]]».
}}<includeonly>{{#if: {{{nocat|}}}{{#ifeq: {{PAGENAME}} | {{SUBPAGENAME}} || {{#ifeq: {{SUBPAGENAME}} | песочница | nocat }} }} ||
{{#switch: {{NAMESPACE}}
| {{ns:10}} = [[Категория:Шаблоны:Недокументированные]]
| {{ns:828}} = {{#ifeq:{{ROOTPAGENAME}}|Песочница||[[Категория:Модули:Недокументированные]]}}
}} }}</includeonly><noinclude>
{{doc-inline}}
Данное сообщение появляется при отсутствующей странице документации, включаемой шаблоном {{t|doc}}.
{{doc-end}}
[[Категория:Шаблоны:Предупреждения]]
[[Категория:Шаблоны:Для документирования шаблонов]]
</noinclude>
7779e82507cacf3a1c77cdb878dd6efafd76b3ce
Шаблон:Doc-end
10
19
37
2024-08-08T15:56:09Z
DuOfOrl
5
Новая страница: «<includeonly></div> </div><templatestyles src="Шаблон:Doc/styles.css" />{{#ifexpr: {{NAMESPACENUMBER}} mod 2 = 1 <!-- Например, [[Обсуждение MediaWiki:Robots.txt]] --> | {{^|1em}} | <div class="ts-doc-footer plainlinks"> {{#ifeq: {{str left|{{PAGENAME}}|9}} | Песочница | | {{#ifeq: {{str rightc|{{PAGENAME}}|10}} | /песочница | | Во избежание поломок страниц, исполь...»
wikitext
text/x-wiki
<includeonly></div>
</div><templatestyles src="Шаблон:Doc/styles.css" />{{#ifexpr: {{NAMESPACENUMBER}} mod 2 = 1 <!-- Например, [[Обсуждение MediaWiki:Robots.txt]] -->
| {{^|1em}}
| <div class="ts-doc-footer plainlinks">
{{#ifeq: {{str left|{{PAGENAME}}|9}}
| Песочница
|
| {{#ifeq: {{str rightc|{{PAGENAME}}|10}}
| /песочница
|
| Во избежание поломок страниц, использующих этот {{#ifeq: {{NAMESPACE}}
| Модуль
| модуль
| шаблон
}}, экспериментируйте в [[Анонпедия:Правка и тестирование шаблонов в песочнице|песочнице]] <small style="font-style:normal;">({{#ifexist: {{FULLPAGENAME}}/песочница
| [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit}} редактировать] {{!}} [{{fullurl:Special:ComparePages|page1={{FULLPAGENAMEE}}&page2={{FULLPAGENAMEE}}/песочница}} разница] {{#ifexist: {{FULLPAGENAME}}/тесты | {{!}} [[{{FULLPAGENAME}}/тесты|тесты]] }}
| {{#ifeq: {{NAMESPACE}} | Модуль | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit}} создать] | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit&preload=Шаблон:Doc/предзагрузка-песочница}} создать] {{!}} [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit&preload=Шаблон:Doc/зеркало}} зеркало] }}
}})</small> или {{#ifeq: {{NAMESPACE}}
| Модуль
| [[Модуль:Песочница|песочнице для модулей]]
| своём [[ВП:ЛП|личном пространстве]]
}}.<br>
}}
}}{{#ifexist: {{FULLPAGENAME}}/doc | Пожалуйста, добавляйте категории на подстраницу [[/doc]]. }}[[Special:PrefixIndex/{{FULLPAGENAME}}/|Подстраницы этого {{#ifeq: {{NAMESPACE}}
| Модуль
| модуля
| шаблона
}}]].
</div>
}}</includeonly><noinclude>{{doc}}</noinclude>
d36d959617c1c876b9769c62baf9d6c9a014476a
Шаблон:Ombox
10
20
38
2024-08-08T15:56:53Z
DuOfOrl
5
Новая страница: «{{#invoke:Message box|ombox}}<noinclude> {{doc}}<!-- Add categories and interwikis to the /doc subpage, not here! --></noinclude>»
wikitext
text/x-wiki
{{#invoke:Message box|ombox}}<noinclude>
{{doc}}<!-- Add categories and interwikis to the /doc subpage, not here! --></noinclude>
ab34435c5ebc29de589c9b059e88da5d0e6f16e4
Модуль:Message box
828
21
39
2024-08-08T15:58:46Z
DuOfOrl
5
Новая страница: «-- This is a meta-module for producing message box templates, including -- {{mbox}}, {{ambox}}, {{imbox}}, {{tmbox}}, {{ombox}}, {{cmbox}} and {{fmbox}}. -- Load necessary modules. require('strict') local getArgs local categoryHandler = require('Module:Category handler')._main local yesno = require('Module:Yesno') local boxDate = require('Module:Calendar').bxDate; -- Get a language object for formatDate and ucfirst. local lang = mw.language.getContentLangu...»
Scribunto
text/plain
-- This is a meta-module for producing message box templates, including
-- {{mbox}}, {{ambox}}, {{imbox}}, {{tmbox}}, {{ombox}}, {{cmbox}} and {{fmbox}}.
-- Load necessary modules.
require('strict')
local getArgs
local categoryHandler = require('Module:Category handler')._main
local yesno = require('Module:Yesno')
local boxDate = require('Module:Calendar').bxDate;
-- Get a language object for formatDate and ucfirst.
local lang = mw.language.getContentLanguage()
-- Define constants
local CONFIG_MODULE = 'Module:Message box/configuration'
--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------
local function getTitleObject(...)
-- Get the title object, passing the function through pcall
-- in case we are over the expensive function count limit.
local success, title = pcall(mw.title.new, ...)
if success then
return title
end
end
local function union(t1, t2)
-- Returns the union of two arrays.
local vals = {}
for i, v in ipairs(t1) do
vals[v] = true
end
for i, v in ipairs(t2) do
vals[v] = true
end
local ret = {}
for k in pairs(vals) do
table.insert(ret, k)
end
table.sort(ret)
return ret
end
local function getArgNums(args, prefix)
local nums = {}
for k, v in pairs(args) do
local num = mw.ustring.match(tostring(k), '^' .. prefix .. '([1-9]%d*)$')
if num then
table.insert(nums, tonumber(num))
end
end
table.sort(nums)
return nums
end
-- локальная обёртка, игнорирует таблицу с номерами дня, месяца и года
local function formatDate(txtDateIn, strFormat, params)
local txtDateOut, date, status = boxDate(txtDateIn, strFormat, params)
if status.brk then
return error(status.errorText)
else
return txtDateOut
end
end
--------------------------------------------------------------------------------
-- Box class definition
--------------------------------------------------------------------------------
local MessageBox = {}
MessageBox.__index = MessageBox
function MessageBox.new(boxType, args, cfg)
args = args or {}
local obj = {}
-- Set the title object and the namespace.
obj.title = getTitleObject(args.page) or mw.title.getCurrentTitle()
-- Set the config for our box type.
obj.cfg = cfg[boxType]
if not obj.cfg then
local ns = obj.title.namespace
-- boxType is "mbox" or invalid input
if ns == 0 then
obj.cfg = cfg.ambox -- main namespace
elseif ns == 6 then
obj.cfg = cfg.imbox -- file namespace
elseif ns == 14 then
obj.cfg = cfg.cmbox -- category namespace
else
local nsTable = mw.site.namespaces[ns]
if nsTable and nsTable.isTalk then
obj.cfg = cfg.tmbox -- any talk namespace
else
obj.cfg = cfg.ombox -- other namespaces or invalid input
end
end
end
-- Set the arguments, and remove all blank arguments except for the ones
-- listed in cfg.allowBlankParams.
do
local newArgs = {}
for k, v in pairs(args) do
if v ~= '' then
newArgs[k] = v
end
end
for i, param in ipairs(obj.cfg.allowBlankParams or {}) do
newArgs[param] = args[param]
end
obj.args = newArgs
end
-- Define internal data structure.
obj.categories = {}
obj.classes = {}
return setmetatable(obj, MessageBox)
end
function MessageBox:addCat(ns, cat, sort)
if not cat then
return nil
end
if sort then
cat = string.format('[[Категория:%s|%s]]', cat, sort)
else
cat = string.format('[[Категория:%s]]', cat)
end
self.categories[ns] = self.categories[ns] or {}
table.insert(self.categories[ns], cat)
end
function MessageBox:addClass(class)
if not class then
return nil
end
table.insert(self.classes, class)
end
function MessageBox:setParameters()
local args = self.args
local cfg = self.cfg
-- Get type data.
self.type = args.type
local typeData = cfg.types[self.type]
self.invalidTypeError = cfg.showInvalidTypeError
and self.type
and not typeData
typeData = typeData or cfg.types[cfg.default]
self.typeClass = typeData.class
self.typeImage = typeData.image
-- Find if the box has been wrongly substituted.
self.isSubstituted = cfg.substCheck and args.subst == 'SUBST'
-- Find whether we are using a small message box.
self.isSmall = cfg.allowSmall and (
cfg.smallParam and args.small == cfg.smallParam
or not cfg.smallParam and yesno(args.small)
)
-- Add attributes, classes and styles.
self.id = args.id
self.name = args.name
if self.name then
self:addClass('mbox-' .. string.gsub(self.name,' ','_'))
end
if yesno(args.plainlinks) ~= false then
self:addClass('plainlinks')
end
for _, class in ipairs(cfg.classes or {}) do
self:addClass(class)
end
if self.isSmall then
self:addClass(cfg.smallClass or 'mbox-small')
end
self:addClass(self.typeClass)
self:addClass(args.class)
self.style = args.style
self.attrs = args.attrs
self.dataLabel1 = args['data-label-1']
self.dataLabel2 = args['data-label-2']
self.dataLabel3 = args['data-label-3']
self.dataValue1 = args['data-value-1']
self.dataValue2 = args['data-value-2']
self.dataValue3 = args['data-value-3']
-- Set text style.
self.textstyle = args.textstyle
-- Find if we are on the template page or not. This functionality is only
-- used if useCollapsibleTextFields is set, or if both cfg.templateCategory
-- and cfg.templateCategoryRequireName are set.
self.useCollapsibleTextFields = cfg.useCollapsibleTextFields
if self.useCollapsibleTextFields
or cfg.templateCategory
and cfg.templateCategoryRequireName
then
self.name = args.name
if self.name then
local templateName = mw.ustring.match(
self.name,
'^[tT][eE][mM][pP][lL][aA][tT][eE][%s_]*:[%s_]*(.*)$'
) or self.name
templateName = ('Template:' .. templateName) or ('Шаблон:' .. templateName)
self.templateTitle = getTitleObject(templateName)
end
self.isTemplatePage = self.templateTitle
and mw.title.equals(self.title, self.templateTitle)
end
-- Process data for collapsible text fields. At the moment these are only
-- used in {{ambox}}.
if self.useCollapsibleTextFields then
-- Get the self.issue value.
if self.isSmall and args.smalltext then
self.issue = args.smalltext
else
if args.sect and args.sect ~= '' or nil then
local issue_sect = args.issue_sect
issue_sect = type(issue_sect) == 'string' and issue_sect ~= '' and issue_sect or nil
local text_sect = args.text_sect
text_sect = type(text_sect) == 'string' and text_sect ~= '' and text_sect or nil
local issues = {}
table.insert(issues, issue_sect)
table.insert(issues, text_sect)
self.issue = table.concat(issues, ' ')
else
local issue = args.issue
issue = type(issue) == 'string' and issue ~= '' and issue or nil
local text = args.text
text = type(text) == 'string' and text or nil
local issues = {}
table.insert(issues, issue)
table.insert(issues, text)
self.issue = table.concat(issues, ' ')
end
end
-- Get the self.talk value.
local talk = args.talk
-- Show talk links on the template page or template subpages if the talk
-- parameter is blank.
if talk == ''
and self.templateTitle
and (
mw.title.equals(self.templateTitle, self.title)
or self.title:isSubpageOf(self.templateTitle)
)
then
talk = '#'
elseif talk == '' then
talk = nil
end
if talk then
-- If the talk value is a talk page, make a link to that page. Else
-- assume that it's a section heading, and make a link to the talk
-- page of the current page with that section heading.
local talkTitle = getTitleObject(talk)
local talkArgIsTalkPage = true
if not talkTitle or not talkTitle.isTalkPage then
talkArgIsTalkPage = false
talkTitle = getTitleObject(
self.title.text,
mw.site.namespaces[self.title.namespace].talk.id
)
end
if talkTitle and talkTitle.exists then
local talkText = 'Соответствующую дискуссию можно найти на'
if talkArgIsTalkPage then
talkText = string.format(
'%s [[%s|%s]].',
talkText,
talk,
talkTitle.prefixedText
)
else
talkText = string.format(
'%s [[%s#%s|странице обсуждения]].',
talkText,
talkTitle.prefixedText,
talk
)
end
self.talk = talkText
end
end
-- Get other values.
self.fix = args.fix ~= '' and args.fix or nil
local date
if args.date and args.date ~= '' then
local status, result = pcall(formatDate, args.date)
if status then
date = string.format("(<span class='date'>%s</span>)", result)
else
date = string.format("<span class='error'>(Строка «%s» не является верной датой, пожалуйста, укажите дату в формате <code>ГГГГ-ММ-ДД</code>)</span>", args.date)
end
elseif args.date == '' and self.isTemplatePage then
date = string.format("(<span class='date'>%s</span>)", formatDate( lang:formatDate('Y-m-d') ) ) -- тут возникновения ошибки, связанной с пользовательским вводом, не будет
end
if date then
self.date = string.format(" <span class='mbox-date'>''%s''</span>", date)
end
self.info = args.info
if yesno(args.removalnotice) then
self.removalNotice = cfg.removalNotice
end
if args.shortFix then
self.shortFix = args.shortFix
end
end
-- Set the non-collapsible text field. At the moment this is used by all box
-- types other than ambox, and also by ambox when small=yes.
if self.isSmall then
self.text = args.smalltext or args.text
else
self.text = args.text
self.textsmall = args['text-small']
end
-- Set the below row.
self.below = cfg.below and args.below
-- General image settings.
self.imageCellDiv = not self.isSmall and cfg.imageCellDiv
self.imageEmptyCell = cfg.imageEmptyCell
if cfg.imageEmptyCellStyle then
self.imageEmptyCellStyle = 'border:none;padding:0px;width:1px'
end
-- Left image settings.
local imageLeft = self.isSmall and args.smallimage or args.image
if cfg.imageCheckBlank and imageLeft ~= 'blank' and imageLeft ~= 'none' and imageLeft ~= ''
or not cfg.imageCheckBlank and imageLeft ~= 'none'
then
self.imageLeft = imageLeft
if not imageLeft then
local imageSize = self.isSmall
and (cfg.imageSmallSize or '30x30px')
or cfg.imageSize
or '40x40px'
self.imageLeft = string.format('[[File:%s|%s|alt=]]', self.typeImage
or 'Information icon4.svg', imageSize)
end
end
-- Right image settings.
local imageRight = self.isSmall and args.smallimageright or args.imageright
if not (cfg.imageRightNone and imageRight == 'none') then
self.imageRight = imageRight
end
-- set templatestyles
self.base_templatestyles = cfg.templatestyles
end
function MessageBox:setMainspaceCategories()
local args = self.args
local cfg = self.cfg
local date = nil
if not cfg.allowMainspaceCategories then
return nil
end
local nums = {}
for _, prefix in ipairs{'cat', 'category', 'all'} do
args[prefix .. '1'] = args[prefix]
nums = union(nums, getArgNums(args, prefix))
end
-- The following is roughly equivalent to the old {{Ambox/category}}.
local status, result = pcall(formatDate, args.date, 'xg Y')
if status then
date = result
end
date = type(date) == 'string' and date
local preposition = 'с'
local suffix = 'года'
for _, num in ipairs(nums) do
local mainCat = args['cat' .. tostring(num)]
or args['category' .. tostring(num)]
local allCat = args['all' .. tostring(num)]
mainCat = type(mainCat) == 'string' and mainCat
allCat = type(allCat) == 'string' and allCat
if mainCat and date and date ~= '' then
local catTitle = string.format('%s %s %s %s', mainCat, preposition, date, suffix)
self:addCat(0, catTitle)
catTitle = getTitleObject('Категория:' .. catTitle)
local status, result = pcall(formatDate, args.date)
if not status then
self:addCat(0, 'Википедия:Статьи с недопустимым параметром даты в шаблоне-сообщении')
end
elseif mainCat and (not date or date == '') then
self:addCat(0, mainCat)
end
if allCat then
self:addCat(0, allCat)
end
end
end
function MessageBox:setTemplateCategories()
local args = self.args
local cfg = self.cfg
-- Add template categories.
if cfg.templateCategory then
if cfg.templateCategoryRequireName then
if self.isTemplatePage then
self:addCat(10, cfg.templateCategory)
end
elseif not self.title.isSubpage then
self:addCat(10, cfg.templateCategory)
end
end
-- Add template error categories.
if cfg.templateErrorCategory then
local templateErrorCategory = cfg.templateErrorCategory
local templateCat, templateSort
if not self.name and not self.title.isSubpage then
templateCat = templateErrorCategory
elseif self.isTemplatePage then
local paramsToCheck = cfg.templateErrorParamsToCheck or {}
local count = 0
for i, param in ipairs(paramsToCheck) do
if not args[param] then
count = count + 1
end
end
if count > 0 then
templateCat = templateErrorCategory
templateSort = tostring(count)
end
if self.categoryNums and #self.categoryNums > 0 then
templateCat = templateErrorCategory
templateSort = 'C'
end
end
self:addCat(10, templateCat, templateSort)
end
end
function MessageBox:setAllNamespaceCategories()
-- Set categories for all namespaces.
if self.invalidTypeError then
local allSort = (self.title.namespace == 0 and 'Main:' or '') .. self.title.prefixedText
self:addCat('all', 'Википедия:Необходимо исправить параметр в шаблоне-сообщении', allSort)
end
if self.isSubstituted then
self:addCat('all', 'Википедия:Страницы с ошибочно подставленными шаблонами')
end
if self.isSmall then
self:addCat(0, 'Википедия:Страницы с малыми шаблонами-сообщениями')
end
end
function MessageBox:setCategories()
if self.title.namespace == 0 then
self:setMainspaceCategories()
elseif self.title.namespace == 10 then
self:setTemplateCategories()
end
self:setAllNamespaceCategories()
end
function MessageBox:renderCategories()
-- Convert category tables to strings and pass them through
-- [[Module:Category handler]].
return categoryHandler{
main = table.concat(self.categories[0] or {}),
template = table.concat(self.categories[10] or {}),
all = table.concat(self.categories.all or {}),
nocat = self.args.nocat,
page = self.args.page
}
end
function MessageBox:export()
local root = mw.html.create()
-- Add the subst check error.
if self.isSubstituted and self.name then
root:tag('b')
:addClass('error')
:wikitext(string.format(
'Шаблон <code>%s[[Шаблон:%s|%s]]%s</code> был неккоректно подставлен.',
mw.text.nowiki('{{'), self.name, self.name, mw.text.nowiki('}}')
))
end
-- Conditional TemplateStyles loading
if self.base_templatestyles then
local frame = mw.getCurrentFrame()
root:wikitext(frame:extensionTag{
name = 'templatestyles',
args = { src = self.base_templatestyles },
})
end
-- Create the box table.
local boxTable = root:tag('table')
boxTable:attr('id', self.id or nil)
for i, class in ipairs(self.classes or {}) do
boxTable:addClass(class or nil)
end
boxTable
:cssText(self.style or nil)
:attr('role', 'presentation')
if self.dataLabel1 then
boxTable:attr('data-' .. self.dataLabel1, self.dataValue1)
end
if self.dataLabel2 then
boxTable:attr('data-' .. self.dataLabel2, self.dataValue2)
end
if self.dataLabel3 then
boxTable:attr('data-' .. self.dataLabel3, self.dataValue3)
end
if self.attrs then
boxTable:attr(self.attrs)
end
-- Add the left-hand image.
local row = boxTable:tag('tr')
if self.imageLeft then
local imageLeftCell = row:tag('td'):addClass('mbox-image')
if self.imageCellDiv then
-- If we are using a div, redefine imageLeftCell so that the image
-- is inside it. Divs use style="width: 52px;", which limits the
-- image width to 52px. If any images in a div are wider than that,
-- they may overlap with the text or cause other display problems.
imageLeftCell = imageLeftCell:tag('div'):css('width', '52px')
end
imageLeftCell:wikitext(self.imageLeft or nil)
elseif self.imageEmptyCell then
-- Some message boxes define an empty cell if no image is specified, and
-- some don't. The old template code in templates where empty cells are
-- specified gives the following hint: "No image. Cell with some width
-- or padding necessary for text cell to have 100% width."
row:tag('td')
:addClass('mbox-empty-cell')
:cssText(self.imageEmptyCellStyle or nil)
end
-- Add the text.
local textCell = row:tag('td'):addClass('mbox-text')
if self.useCollapsibleTextFields then
-- The message box uses advanced text parameters that allow things to be
-- collapsible. At the moment, only ambox uses this.
textCell:cssText(self.textstyle or nil)
local textCellDiv = textCell:tag('div')
textCellDiv
:addClass('mbox-text-div')
:wikitext(self.issue or nil)
local textsmallCellDiv = textCell:tag('div')
textsmallCellDiv
:addClass('mbox-textsmall-div hide-when-compact')
:cssText(self.textsmallstyle)
:wikitext(self.textsmall or nil)
if (self.talk or self.fix) and not self.isSmall then
textsmallCellDiv:tag('span')
:addClass('hide-when-compact')
:wikitext(self.fix and (' ' .. self.fix) or nil)
:wikitext(self.talk and (' ' .. self.talk) or nil)
end
if self.textsmall or self.fix or self.talk then
textsmallCellDiv:wikitext(self.date and (' ' .. self.date) or nil)
else
textCellDiv:wikitext(self.date and (' ' .. self.date) or nil)
end
if self.info and not self.isSmall then
textsmallCellDiv
:tag('span')
:addClass('hide-when-compact')
:wikitext(self.info and (' ' .. self.info) or nil)
end
if self.removalNotice then
textsmallCellDiv:tag('small')
:addClass('hide-when-compact')
:tag('i')
:wikitext(string.format(" (%s)", self.removalNotice))
end
if self.shortFix then
textCell:tag('div')
:addClass('mbox-multiply')
:tag('span')
:wikitext(string.format("%s", self.shortFix))
:tag('span')
:wikitext(self.date and (' ' .. self.date) or nil)
end
else
-- Default text formatting - anything goes.
textCell
:cssText(self.textstyle or nil)
:wikitext(self.text or nil)
end
-- Add the right-hand image.
if self.imageRight then
local imageRightCell = row:tag('td'):addClass('mbox-imageright')
if self.imageCellDiv then
-- If we are using a div, redefine imageRightCell so that the image
-- is inside it.
imageRightCell = imageRightCell:tag('div'):css('width', '52px')
end
imageRightCell
:wikitext(self.imageRight or nil)
end
-- Add the below row.
if self.below then
boxTable:tag('tr')
:tag('td')
:attr('colspan', self.imageRight and '3' or '2')
:addClass('mbox-text')
:cssText(self.textstyle or nil)
:wikitext(self.below or nil)
end
-- Add error message for invalid type parameters.
if self.invalidTypeError then
root:tag('div')
:css('text-align', 'center')
:wikitext(string.format(
'Этот шаблон-сообщение использует неверный параметр "type=%s", необходимо исправить.',
self.type or ''
))
end
-- Add categories.
root:wikitext(self:renderCategories() or nil)
return tostring(root)
end
--------------------------------------------------------------------------------
-- Exports
--------------------------------------------------------------------------------
local p, mt = {}, {}
function p._exportClasses()
-- For testing.
return {
MessageBox = MessageBox
}
end
function p.main(boxType, args, cfgTables)
local box = MessageBox.new(boxType, args, cfgTables or mw.loadData(CONFIG_MODULE))
box:setParameters()
box:setCategories()
return box:export()
end
function mt.__index(t, k)
return function (frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
return t.main(k, getArgs(frame, {trim = false, removeBlanks = false}))
end
end
return setmetatable(p, mt)
f2539b657a9cdadde7c0dd5ad270d3095b2bdd54
137
39
2024-08-09T17:01:57Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
-- This is a meta-module for producing message box templates, including
-- {{mbox}}, {{ambox}}, {{imbox}}, {{tmbox}}, {{ombox}}, {{cmbox}} and {{fmbox}}.
-- Load necessary modules.
require('strict')
local getArgs
local categoryHandler = require('Module:Category handler')._main
local yesno = require('Module:Yesno')
local boxDate = require('Module:Calendar').bxDate;
-- Get a language object for formatDate and ucfirst.
local lang = mw.language.getContentLanguage()
-- Define constants
local CONFIG_MODULE = 'Module:Message box/configuration'
--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------
local function getTitleObject(...)
-- Get the title object, passing the function through pcall
-- in case we are over the expensive function count limit.
local success, title = pcall(mw.title.new, ...)
if success then
return title
end
end
local function union(t1, t2)
-- Returns the union of two arrays.
local vals = {}
for i, v in ipairs(t1) do
vals[v] = true
end
for i, v in ipairs(t2) do
vals[v] = true
end
local ret = {}
for k in pairs(vals) do
table.insert(ret, k)
end
table.sort(ret)
return ret
end
local function getArgNums(args, prefix)
local nums = {}
for k, v in pairs(args) do
local num = mw.ustring.match(tostring(k), '^' .. prefix .. '([1-9]%d*)$')
if num then
table.insert(nums, tonumber(num))
end
end
table.sort(nums)
return nums
end
-- локальная обёртка, игнорирует таблицу с номерами дня, месяца и года
local function formatDate(txtDateIn, strFormat, params)
local txtDateOut, date, status = boxDate(txtDateIn, strFormat, params)
if status.brk then
return error(status.errorText)
else
return txtDateOut
end
end
--------------------------------------------------------------------------------
-- Box class definition
--------------------------------------------------------------------------------
local MessageBox = {}
MessageBox.__index = MessageBox
function MessageBox.new(boxType, args, cfg)
args = args or {}
local obj = {}
-- Set the title object and the namespace.
obj.title = getTitleObject(args.page) or mw.title.getCurrentTitle()
-- Set the config for our box type.
obj.cfg = cfg[boxType]
if not obj.cfg then
local ns = obj.title.namespace
-- boxType is "mbox" or invalid input
if ns == 0 then
obj.cfg = cfg.ambox -- main namespace
elseif ns == 6 then
obj.cfg = cfg.imbox -- file namespace
elseif ns == 14 then
obj.cfg = cfg.cmbox -- category namespace
else
local nsTable = mw.site.namespaces[ns]
if nsTable and nsTable.isTalk then
obj.cfg = cfg.tmbox -- any talk namespace
else
obj.cfg = cfg.ombox -- other namespaces or invalid input
end
end
end
-- Set the arguments, and remove all blank arguments except for the ones
-- listed in cfg.allowBlankParams.
do
local newArgs = {}
for k, v in pairs(args) do
if v ~= '' then
newArgs[k] = v
end
end
for i, param in ipairs(obj.cfg.allowBlankParams or {}) do
newArgs[param] = args[param]
end
obj.args = newArgs
end
-- Define internal data structure.
obj.categories = {}
obj.classes = {}
return setmetatable(obj, MessageBox)
end
function MessageBox:addCat(ns, cat, sort)
if not cat then
return nil
end
if sort then
cat = string.format('[[Категория:%s|%s]]', cat, sort)
else
cat = string.format('[[Категория:%s]]', cat)
end
self.categories[ns] = self.categories[ns] or {}
table.insert(self.categories[ns], cat)
end
function MessageBox:addClass(class)
if not class then
return nil
end
table.insert(self.classes, class)
end
function MessageBox:setParameters()
local args = self.args
local cfg = self.cfg
-- Get type data.
self.type = args.type
local typeData = cfg.types[self.type]
self.invalidTypeError = cfg.showInvalidTypeError
and self.type
and not typeData
typeData = typeData or cfg.types[cfg.default]
self.typeClass = typeData.class
self.typeImage = typeData.image
-- Find if the box has been wrongly substituted.
self.isSubstituted = cfg.substCheck and args.subst == 'SUBST'
-- Find whether we are using a small message box.
self.isSmall = cfg.allowSmall and (
cfg.smallParam and args.small == cfg.smallParam
or not cfg.smallParam and yesno(args.small)
)
-- Add attributes, classes and styles.
self.id = args.id
self.name = args.name
if self.name then
self:addClass('mbox-' .. string.gsub(self.name,' ','_'))
end
if yesno(args.plainlinks) ~= false then
self:addClass('plainlinks')
end
for _, class in ipairs(cfg.classes or {}) do
self:addClass(class)
end
if self.isSmall then
self:addClass(cfg.smallClass or 'mbox-small')
end
self:addClass(self.typeClass)
self:addClass(args.class)
self.style = args.style
self.attrs = args.attrs
self.dataLabel1 = args['data-label-1']
self.dataLabel2 = args['data-label-2']
self.dataLabel3 = args['data-label-3']
self.dataValue1 = args['data-value-1']
self.dataValue2 = args['data-value-2']
self.dataValue3 = args['data-value-3']
-- Set text style.
self.textstyle = args.textstyle
-- Find if we are on the template page or not. This functionality is only
-- used if useCollapsibleTextFields is set, or if both cfg.templateCategory
-- and cfg.templateCategoryRequireName are set.
self.useCollapsibleTextFields = cfg.useCollapsibleTextFields
if self.useCollapsibleTextFields
or cfg.templateCategory
and cfg.templateCategoryRequireName
then
self.name = args.name
if self.name then
local templateName = mw.ustring.match(
self.name,
'^[tT][eE][mM][pP][lL][aA][tT][eE][%s_]*:[%s_]*(.*)$'
) or self.name
templateName = ('Template:' .. templateName) or ('Шаблон:' .. templateName)
self.templateTitle = getTitleObject(templateName)
end
self.isTemplatePage = self.templateTitle
and mw.title.equals(self.title, self.templateTitle)
end
-- Process data for collapsible text fields. At the moment these are only
-- used in {{ambox}}.
if self.useCollapsibleTextFields then
-- Get the self.issue value.
if self.isSmall and args.smalltext then
self.issue = args.smalltext
else
if args.sect and args.sect ~= '' or nil then
local issue_sect = args.issue_sect
issue_sect = type(issue_sect) == 'string' and issue_sect ~= '' and issue_sect or nil
local text_sect = args.text_sect
text_sect = type(text_sect) == 'string' and text_sect ~= '' and text_sect or nil
local issues = {}
table.insert(issues, issue_sect)
table.insert(issues, text_sect)
self.issue = table.concat(issues, ' ')
else
local issue = args.issue
issue = type(issue) == 'string' and issue ~= '' and issue or nil
local text = args.text
text = type(text) == 'string' and text or nil
local issues = {}
table.insert(issues, issue)
table.insert(issues, text)
self.issue = table.concat(issues, ' ')
end
end
-- Get the self.talk value.
local talk = args.talk
-- Show talk links on the template page or template subpages if the talk
-- parameter is blank.
if talk == ''
and self.templateTitle
and (
mw.title.equals(self.templateTitle, self.title)
or self.title:isSubpageOf(self.templateTitle)
)
then
talk = '#'
elseif talk == '' then
talk = nil
end
if talk then
-- If the talk value is a talk page, make a link to that page. Else
-- assume that it's a section heading, and make a link to the talk
-- page of the current page with that section heading.
local talkTitle = getTitleObject(talk)
local talkArgIsTalkPage = true
if not talkTitle or not talkTitle.isTalkPage then
talkArgIsTalkPage = false
talkTitle = getTitleObject(
self.title.text,
mw.site.namespaces[self.title.namespace].talk.id
)
end
if talkTitle and talkTitle.exists then
local talkText = 'Соответствующую дискуссию можно найти на'
if talkArgIsTalkPage then
talkText = string.format(
'%s [[%s|%s]].',
talkText,
talk,
talkTitle.prefixedText
)
else
talkText = string.format(
'%s [[%s#%s|странице обсуждения]].',
talkText,
talkTitle.prefixedText,
talk
)
end
self.talk = talkText
end
end
-- Get other values.
self.fix = args.fix ~= '' and args.fix or nil
local date
if args.date and args.date ~= '' then
local status, result = pcall(formatDate, args.date)
if status then
date = string.format("(<span class='date'>%s</span>)", result)
else
date = string.format("<span class='error'>(Строка «%s» не является верной датой, пожалуйста, укажите дату в формате <code>ГГГГ-ММ-ДД</code>)</span>", args.date)
end
elseif args.date == '' and self.isTemplatePage then
date = string.format("(<span class='date'>%s</span>)", formatDate( lang:formatDate('Y-m-d') ) ) -- тут возникновения ошибки, связанной с пользовательским вводом, не будет
end
if date then
self.date = string.format(" <span class='mbox-date'>''%s''</span>", date)
end
self.info = args.info
if yesno(args.removalnotice) then
self.removalNotice = cfg.removalNotice
end
if args.shortFix then
self.shortFix = args.shortFix
end
end
-- Set the non-collapsible text field. At the moment this is used by all box
-- types other than ambox, and also by ambox when small=yes.
if self.isSmall then
self.text = args.smalltext or args.text
else
self.text = args.text
self.textsmall = args['text-small']
end
-- Set the below row.
self.below = cfg.below and args.below
-- General image settings.
self.imageCellDiv = not self.isSmall and cfg.imageCellDiv
self.imageEmptyCell = cfg.imageEmptyCell
if cfg.imageEmptyCellStyle then
self.imageEmptyCellStyle = 'border:none;padding:0px;width:1px'
end
-- Left image settings.
local imageLeft = self.isSmall and args.smallimage or args.image
if cfg.imageCheckBlank and imageLeft ~= 'blank' and imageLeft ~= 'none' and imageLeft ~= ''
or not cfg.imageCheckBlank and imageLeft ~= 'none'
then
self.imageLeft = imageLeft
if not imageLeft then
local imageSize = self.isSmall
and (cfg.imageSmallSize or '30x30px')
or cfg.imageSize
or '40x40px'
self.imageLeft = string.format('[[File:%s|%s|alt=]]', self.typeImage
or 'Information icon4.svg', imageSize)
end
end
-- Right image settings.
local imageRight = self.isSmall and args.smallimageright or args.imageright
if not (cfg.imageRightNone and imageRight == 'none') then
self.imageRight = imageRight
end
-- set templatestyles
self.base_templatestyles = cfg.templatestyles
end
function MessageBox:setMainspaceCategories()
local args = self.args
local cfg = self.cfg
local date = nil
if not cfg.allowMainspaceCategories then
return nil
end
local nums = {}
for _, prefix in ipairs{'cat', 'category', 'all'} do
args[prefix .. '1'] = args[prefix]
nums = union(nums, getArgNums(args, prefix))
end
-- The following is roughly equivalent to the old {{Ambox/category}}.
local status, result = pcall(formatDate, args.date, 'xg Y')
if status then
date = result
end
date = type(date) == 'string' and date
local preposition = 'с'
local suffix = 'года'
for _, num in ipairs(nums) do
local mainCat = args['cat' .. tostring(num)]
or args['category' .. tostring(num)]
local allCat = args['all' .. tostring(num)]
mainCat = type(mainCat) == 'string' and mainCat
allCat = type(allCat) == 'string' and allCat
if mainCat and date and date ~= '' then
local catTitle = string.format('%s %s %s %s', mainCat, preposition, date, suffix)
self:addCat(0, catTitle)
catTitle = getTitleObject('Категория:' .. catTitle)
local status, result = pcall(formatDate, args.date)
if not status then
self:addCat(0, 'Википедия:Статьи с недопустимым параметром даты в шаблоне-сообщении')
end
elseif mainCat and (not date or date == '') then
self:addCat(0, mainCat)
end
if allCat then
self:addCat(0, allCat)
end
end
end
function MessageBox:setTemplateCategories()
local args = self.args
local cfg = self.cfg
-- Add template categories.
if cfg.templateCategory then
if cfg.templateCategoryRequireName then
if self.isTemplatePage then
self:addCat(10, cfg.templateCategory)
end
elseif not self.title.isSubpage then
self:addCat(10, cfg.templateCategory)
end
end
-- Add template error categories.
if cfg.templateErrorCategory then
local templateErrorCategory = cfg.templateErrorCategory
local templateCat, templateSort
if not self.name and not self.title.isSubpage then
templateCat = templateErrorCategory
elseif self.isTemplatePage then
local paramsToCheck = cfg.templateErrorParamsToCheck or {}
local count = 0
for i, param in ipairs(paramsToCheck) do
if not args[param] then
count = count + 1
end
end
if count > 0 then
templateCat = templateErrorCategory
templateSort = tostring(count)
end
if self.categoryNums and #self.categoryNums > 0 then
templateCat = templateErrorCategory
templateSort = 'C'
end
end
self:addCat(10, templateCat, templateSort)
end
end
function MessageBox:setAllNamespaceCategories()
-- Set categories for all namespaces.
if self.invalidTypeError then
local allSort = (self.title.namespace == 0 and 'Main:' or '') .. self.title.prefixedText
self:addCat('all', 'Википедия:Необходимо исправить параметр в шаблоне-сообщении', allSort)
end
if self.isSubstituted then
self:addCat('all', 'Википедия:Страницы с ошибочно подставленными шаблонами')
end
if self.isSmall then
self:addCat(0, 'Википедия:Страницы с малыми шаблонами-сообщениями')
end
end
function MessageBox:setCategories()
if self.title.namespace == 0 then
self:setMainspaceCategories()
elseif self.title.namespace == 10 then
self:setTemplateCategories()
end
self:setAllNamespaceCategories()
end
function MessageBox:renderCategories()
-- Convert category tables to strings and pass them through
-- [[Module:Category handler]].
return categoryHandler{
main = table.concat(self.categories[0] or {}),
template = table.concat(self.categories[10] or {}),
all = table.concat(self.categories.all or {}),
nocat = self.args.nocat,
page = self.args.page
}
end
function MessageBox:export()
local root = mw.html.create()
-- Add the subst check error.
if self.isSubstituted and self.name then
root:tag('b')
:addClass('error')
:wikitext(string.format(
'Шаблон <code>%s[[Шаблон:%s|%s]]%s</code> был неккоректно подставлен.',
mw.text.nowiki('{{'), self.name, self.name, mw.text.nowiki('}}')
))
end
-- Conditional TemplateStyles loading
if self.base_templatestyles then
local frame = mw.getCurrentFrame()
root:wikitext(frame:extensionTag{
name = 'templatestyles',
args = { src = self.base_templatestyles },
})
end
-- Create the box table.
local boxTable = root:tag('table')
boxTable:attr('id', self.id or nil)
for i, class in ipairs(self.classes or {}) do
boxTable:addClass(class or nil)
end
boxTable
:cssText(self.style or nil)
:attr('role', 'presentation')
if self.dataLabel1 then
boxTable:attr('data-' .. self.dataLabel1, self.dataValue1)
end
if self.dataLabel2 then
boxTable:attr('data-' .. self.dataLabel2, self.dataValue2)
end
if self.dataLabel3 then
boxTable:attr('data-' .. self.dataLabel3, self.dataValue3)
end
if self.attrs then
boxTable:attr(self.attrs)
end
-- Add the left-hand image.
local row = boxTable:tag('tr')
if self.imageLeft then
local imageLeftCell = row:tag('td'):addClass('mbox-image')
if self.imageCellDiv then
-- If we are using a div, redefine imageLeftCell so that the image
-- is inside it. Divs use style="width: 52px;", which limits the
-- image width to 52px. If any images in a div are wider than that,
-- they may overlap with the text or cause other display problems.
imageLeftCell = imageLeftCell:tag('div'):css('width', '52px')
end
imageLeftCell:wikitext(self.imageLeft or nil)
elseif self.imageEmptyCell then
-- Some message boxes define an empty cell if no image is specified, and
-- some don't. The old template code in templates where empty cells are
-- specified gives the following hint: "No image. Cell with some width
-- or padding necessary for text cell to have 100% width."
row:tag('td')
:addClass('mbox-empty-cell')
:cssText(self.imageEmptyCellStyle or nil)
end
-- Add the text.
local textCell = row:tag('td'):addClass('mbox-text')
if self.useCollapsibleTextFields then
-- The message box uses advanced text parameters that allow things to be
-- collapsible. At the moment, only ambox uses this.
textCell:cssText(self.textstyle or nil)
local textCellDiv = textCell:tag('div')
textCellDiv
:addClass('mbox-text-div')
:wikitext(self.issue or nil)
local textsmallCellDiv = textCell:tag('div')
textsmallCellDiv
:addClass('mbox-textsmall-div hide-when-compact')
:cssText(self.textsmallstyle)
:wikitext(self.textsmall or nil)
if (self.talk or self.fix) and not self.isSmall then
textsmallCellDiv:tag('span')
:addClass('hide-when-compact')
:wikitext(self.fix and (' ' .. self.fix) or nil)
:wikitext(self.talk and (' ' .. self.talk) or nil)
end
if self.textsmall or self.fix or self.talk then
textsmallCellDiv:wikitext(self.date and (' ' .. self.date) or nil)
else
textCellDiv:wikitext(self.date and (' ' .. self.date) or nil)
end
if self.info and not self.isSmall then
textsmallCellDiv
:tag('span')
:addClass('hide-when-compact')
:wikitext(self.info and (' ' .. self.info) or nil)
end
if self.removalNotice then
textsmallCellDiv:tag('small')
:addClass('hide-when-compact')
:tag('i')
:wikitext(string.format(" (%s)", self.removalNotice))
end
if self.shortFix then
textCell:tag('div')
:addClass('mbox-multiply')
:tag('span')
:wikitext(string.format("%s", self.shortFix))
:tag('span')
:wikitext(self.date and (' ' .. self.date) or nil)
end
else
-- Default text formatting - anything goes.
textCell
:cssText(self.textstyle or nil)
:wikitext(self.text or nil)
end
-- Add the right-hand image.
if self.imageRight then
local imageRightCell = row:tag('td'):addClass('mbox-imageright')
if self.imageCellDiv then
-- If we are using a div, redefine imageRightCell so that the image
-- is inside it.
imageRightCell = imageRightCell:tag('div'):css('width', '52px')
end
imageRightCell
:wikitext(self.imageRight or nil)
end
-- Add the below row.
if self.below then
boxTable:tag('tr')
:tag('td')
:attr('colspan', self.imageRight and '3' or '2')
:addClass('mbox-text')
:cssText(self.textstyle or nil)
:wikitext(self.below or nil)
end
-- Add error message for invalid type parameters.
if self.invalidTypeError then
root:tag('div')
:css('text-align', 'center')
:wikitext(string.format(
'Этот шаблон-сообщение использует неверный параметр "type=%s", необходимо исправить.',
self.type or ''
))
end
-- Add categories.
root:wikitext(self:renderCategories() or nil)
return tostring(root)
end
--------------------------------------------------------------------------------
-- Exports
--------------------------------------------------------------------------------
local p, mt = {}, {}
function p._exportClasses()
-- For testing.
return {
MessageBox = MessageBox
}
end
function p.main(boxType, args, cfgTables)
local box = MessageBox.new(boxType, args, cfgTables or mw.loadData(CONFIG_MODULE))
box:setParameters()
box:setCategories()
return box:export()
end
function mt.__index(t, k)
return function (frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
return t.main(k, getArgs(frame, {trim = false, removeBlanks = false}))
end
end
return setmetatable(p, mt)
f2539b657a9cdadde7c0dd5ad270d3095b2bdd54
Модуль:Category handler
828
31
49
2024-08-08T16:13:24Z
DuOfOrl
5
Новая страница: «-------------------------------------------------------------------------------- -- -- -- CATEGORY HANDLER -- -- -- -- This module implements the {{category handler}} template in Lua, -- -- with a few improvements: all namespaces and all n...»
Scribunto
text/plain
--------------------------------------------------------------------------------
-- --
-- CATEGORY HANDLER --
-- --
-- This module implements the {{category handler}} template in Lua, --
-- with a few improvements: all namespaces and all namespace aliases --
-- are supported, and namespace names are detected automatically for --
-- the local wiki. This module requires [[Module:Namespace detect]] --
-- and [[Module:Yesno]] to be available on the local wiki. It can be --
-- configured for different wikis by altering the values in --
-- [[Module:Category handler/config]], and pages can be blacklisted --
-- from categorisation by using [[Module:Category handler/blacklist]]. --
-- --
--------------------------------------------------------------------------------
-- Load required modules
local yesno = require('Module:Yesno')
-- Lazily load things we don't always need
local mShared, mappings
local p = {}
--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------
local function trimWhitespace(s, removeBlanks)
if type(s) ~= 'string' then
return s
end
s = s:match('^%s*(.-)%s*$')
if removeBlanks then
if s ~= '' then
return s
else
return nil
end
else
return s
end
end
--------------------------------------------------------------------------------
-- CategoryHandler class
--------------------------------------------------------------------------------
local CategoryHandler = {}
CategoryHandler.__index = CategoryHandler
function CategoryHandler.new(data, args)
local obj = setmetatable({ _data = data, _args = args }, CategoryHandler)
-- Set the title object
do
local pagename = obj:parameter('demopage')
local success, titleObj
if pagename then
success, titleObj = pcall(mw.title.new, pagename)
end
if success and titleObj then
obj.title = titleObj
if titleObj == mw.title.getCurrentTitle() then
obj._usesCurrentTitle = true
end
else
obj.title = mw.title.getCurrentTitle()
obj._usesCurrentTitle = true
end
end
-- Set suppression parameter values
for _, key in ipairs{'nocat', 'categories'} do
local value = obj:parameter(key)
value = trimWhitespace(value, true)
obj['_' .. key] = yesno(value)
end
do
local subpage = obj:parameter('subpage')
local category2 = obj:parameter('category2')
if type(subpage) == 'string' then
subpage = mw.ustring.lower(subpage)
end
if type(category2) == 'string' then
subpage = mw.ustring.lower(category2)
end
obj._subpage = trimWhitespace(subpage, true)
obj._category2 = trimWhitespace(category2) -- don't remove blank values
end
return obj
end
function CategoryHandler:parameter(key)
local parameterNames = self._data.parameters[key]
local pntype = type(parameterNames)
if pntype == 'string' or pntype == 'number' then
return self._args[parameterNames]
elseif pntype == 'table' then
for _, name in ipairs(parameterNames) do
local value = self._args[name]
if value ~= nil then
return value
end
end
return nil
else
error(string.format(
'invalid config key "%s"',
tostring(key)
), 2)
end
end
function CategoryHandler:isSuppressedByArguments()
return
-- See if a category suppression argument has been set.
self._nocat == true
or self._categories == false
or (
self._category2
and self._category2 ~= self._data.category2Yes
and self._category2 ~= self._data.category2Negative
)
-- Check whether we are on a subpage, and see if categories are
-- suppressed based on our subpage status.
or self._subpage == self._data.subpageNo and self.title.isSubpage
or self._subpage == self._data.subpageOnly and not self.title.isSubpage
end
function CategoryHandler:shouldSkipBlacklistCheck()
-- Check whether the category suppression arguments indicate we
-- should skip the blacklist check.
return self._nocat == false
or self._categories == true
or self._category2 == self._data.category2Yes
end
function CategoryHandler:matchesBlacklist()
if self._usesCurrentTitle then
return self._data.currentTitleMatchesBlacklist
else
mShared = mShared or require('Module:Category handler/shared')
return mShared.matchesBlacklist(
self.title.prefixedText,
mw.loadData('Module:Category handler/blacklist')
)
end
end
function CategoryHandler:isSuppressed()
-- Find if categories are suppressed by either the arguments or by
-- matching the blacklist.
return self:isSuppressedByArguments()
or not self:shouldSkipBlacklistCheck() and self:matchesBlacklist()
end
function CategoryHandler:getNamespaceParameters()
if self._usesCurrentTitle then
return self._data.currentTitleNamespaceParameters
else
if not mappings then
mShared = mShared or require('Module:Category handler/shared')
mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData
end
return mShared.getNamespaceParameters(
self.title,
mappings
)
end
end
function CategoryHandler:namespaceParametersExist()
-- Find whether any namespace parameters have been specified.
-- We use the order "all" --> namespace params --> "other" as this is what
-- the old template did.
if self:parameter('all') then
return true
end
if not mappings then
mShared = mShared or require('Module:Category handler/shared')
mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData
end
for ns, params in pairs(mappings) do
for i, param in ipairs(params) do
if self._args[param] then
return true
end
end
end
if self:parameter('other') then
return true
end
return false
end
function CategoryHandler:getCategories()
local params = self:getNamespaceParameters()
local nsCategory
for i, param in ipairs(params) do
local value = self._args[param]
if value ~= nil then
nsCategory = value
break
end
end
if nsCategory ~= nil or self:namespaceParametersExist() then
-- Namespace parameters exist - advanced usage.
if nsCategory == nil then
nsCategory = self:parameter('other')
end
local ret = {self:parameter('all')}
local numParam = tonumber(nsCategory)
if numParam and numParam >= 1 and math.floor(numParam) == numParam then
-- nsCategory is an integer
ret[#ret + 1] = self._args[numParam]
else
ret[#ret + 1] = nsCategory
end
if #ret < 1 then
return nil
else
return table.concat(ret)
end
elseif self._data.defaultNamespaces[self.title.namespace] then
-- Namespace parameters don't exist, simple usage.
return self._args[1]
end
return nil
end
--------------------------------------------------------------------------------
-- Exports
--------------------------------------------------------------------------------
local p = {}
function p._exportClasses()
-- Used for testing purposes.
return {
CategoryHandler = CategoryHandler
}
end
function p._main(args, data)
data = data or mw.loadData('Module:Category handler/data')
local handler = CategoryHandler.new(data, args)
if handler:isSuppressed() then
return nil
end
return handler:getCategories()
end
function p.main(frame, data)
data = data or mw.loadData('Module:Category handler/data')
local args = require('Module:Arguments').getArgs(frame, {
wrappers = data.wrappers,
valueFunc = function (k, v)
v = trimWhitespace(v)
if type(k) == 'number' then
if v ~= '' then
return v
else
return nil
end
else
return v
end
end
})
return p._main(args, data)
end
return p
b74dd63857b24904ac452429b11213f18647471f
Шаблон:Documentation
10
39
57
2024-08-09T12:44:31Z
DuOfOrl
5
Перенаправление на [[Шаблон:Doc]]
wikitext
text/x-wiki
#REDIRECT [[Шаблон:Doc]]
f1179db1364f4b0309c635b50e5682bfd279e109
Шаблон:Очищать кэш
10
55
83
2024-08-09T15:45:42Z
DuOfOrl
5
Новая страница: «<includeonly><nowiki />{{#switch: {{lcfirst: {{{1|}}} }} | hourly | ежечасно = [[Категория:Анонпедия:Страницы с ежечасно очищаемым кэшем]] | daily | ежедневно | = [[Категория:Анонпедия:Страницы с ежедневно очищаемым кэшем]] | null edit | нулевой правкой = Категория:Анонпедия:Страницы с ежедневн...»
wikitext
text/x-wiki
<includeonly><nowiki />{{#switch: {{lcfirst: {{{1|}}} }}
| hourly
| ежечасно = [[Категория:Анонпедия:Страницы с ежечасно очищаемым кэшем]]
| daily
| ежедневно
| = [[Категория:Анонпедия:Страницы с ежедневно очищаемым кэшем]]
| null edit
| нулевой правкой = [[Категория:Анонпедия:Страницы с ежедневно совершаемой нулевой правкой]]
| [[Категория:Анонпедия:Страницы c нераспознанным значением параметра шаблона «Очищать кэш»]]
}}<nowiki /></includeonly><noinclude>{{doc}}</noinclude>
8f18e85d9593a7af672832dddcfc5c20eb8797a6
Модуль:Calendar
828
62
97
96
2024-08-09T15:56:44Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
local p = {}
-- Необходимые модули и переменные
local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')
local mwlang = mw.getContentLanguage()
local err = "―" -- NthDay nil result
local tCon = table.concat
-- 00) Блок многократно используемых списков
local bool_to_number={ [true]=1, [false]=0 }
local monthlang = {"января","февраля","марта","апреля","мая","июня","июля","августа","сентября","октября","ноября","декабря"}
local month_to_num = {["января"]=1,["февраля"]=2,["марта"]=3,["апреля"]=4,["мая"]=5,["июня"]=6,
["июля"]=7,["августа"]=8,["сентября"]=9,["октября"]=10,["ноября"]=11,["декабря"]=12,["-"]=""}
local monthd = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
local params = { {"г", "g"}, {"ю", "j"}}
local comment = { '<span style="border-bottom: 1px dotted; cursor: help" title="по юлианскому календарю">','</span>'}
-- duplicates:
-- AST, BST, CST, ECT, IST, MST, PST, SST,
local known_tzs = {
ACDT='+10:30', ACST='+09:30', ACT ='+08:00', ADT ='-03:00', AEDT ='+11:00',
AEST='+10:00', AFT ='+04:30', AKDT='-08:00', AKST ='-09:00', AMST ='+05:00',
AMT ='+04:00', ART ='-03:00', AST ='+03:00', AST ='+04:00', AST ='+03:00',
AST ='-04:00', AWDT='+09:00', AWST='+08:00', AZOST='-01:00', AZT ='+04:00',
BDT ='+08:00', BIOT='+06:00', BIT ='-12:00', BOT ='-04:00', BRT ='-03:00',
BST ='+06:00', BST ='+01:00', BTT ='+06:00', CAT ='+02:00', CCT ='+06:30',
CDT ='-05:00', CEDT='+02:00', CEST='+02:00', CET ='+01:00', CHAST='+12:45',
CIST='-08:00', CKT ='-10:00', CLST='-03:00', CLT ='-04:00', COST ='-04:00',
COT ='-05:00', CST ='-06:00', CST ='+08:00', CVT ='-01:00', CXT ='+07:00',
CHST='+10:00', DFT ='+01:00', EAST='-06:00', EAT ='+03:00', ECT ='-04:00',
ECT ='-05:00', EDT ='-04:00', EEDT='+03:00', EEST ='+03:00', EET ='+02:00',
EST ='-05:00', FJT ='+12:00', FKST='-03:00', FKT ='-04:00', GALT ='-06:00',
GET ='+04:00', GFT ='-03:00', GILT='+12:00', GIT ='-09:00', GMT ='+00:00',
GST ='-02:00', GYT ='-04:00', HADT='-09:00', HAST ='-10:00', HKT ='+08:00',
HMT ='+05:00', HST ='-10:00', IRKT='+08:00', IRST ='+03:30', IST ='+05:30',
IST ='+01:00', IST ='+02:00', JST ='+09:00', KRAT ='+07:00', KST ='+09:00',
LHST='+10:30', LINT='+14:00', MAGT='+11:00', MDT ='-06:00', MIT ='-09:30',
MSD ='+04:00', MSK ='+03:00', MST ='+08:00', MST ='-07:00', MST ='+06:30',
MUT ='+04:00', NDT ='-02:30', NFT ='+11:30', NPT ='+05:45', NST ='-03:30',
NT ='-03:30', OMST='+06:00', PDT ='-07:00', PETT ='+12:00', PHOT ='+13:00',
PKT ='+05:00', PST ='-08:00', PST ='+08:00', RET ='+04:00', SAMT ='+04:00',
SAST='+02:00', SBT ='+11:00', SCT ='+04:00', SLT ='+05:30', SST ='-11:00',
SST ='+08:00', TAHT='-10:00', THA ='+07:00', UTC ='+00:00', UYST ='-02:00',
UYT ='-03:00', VET ='-04:30', VLAT='+10:00', WAT ='+01:00', WEDT ='+01:00',
WEST='+01:00', WET ='+00:00', YAKT='+09:00', YEKT ='+05:00',
-- US Millitary (for RFC-822)
Z='+00:00', A='-01:00', M='-12:00', N='+01:00', Y='+12:00',
}
local category = {
["no_parameters"]=
"<!--[[Категория:Модуль:Calendar:Страницы без параметров]]-->",
["incomplete_parameters"]=
"<!--[[Категория:Модуль:Calendar:Страницы с неполными или некорректными параметрами]]-->",
["without_verification"]=
"<!--[[Категория:Модуль:Calendar:Страницы без проверки параметров]]-->",
["erroneous_parameters"]=
"<!--[[Категория:Модуль:Calendar:Страницы с ошибочными параметрами]]-->"
}
-- несколько параметров передаются вместе с кодом ошибки в таблице, один может быть передан простым значением
local e = {
["start"]="<span class=error>Ошибка: ",
["ending"]=".</span>",
["no_pattern_match"]="строка «%s» не совпадает с заданными паттернами",
["no_valid_date"]="дата «%s» не является корректной",
["wrong_jd"]="юлианская дата %s вне диапазона",
["no_data"]="нет входящих данных",
["too_many_arguments"]="ожидается менее %i аргументов",
["too_little_arguments"]="ожидается более %i аргументов",
["wrong_calculation"]="даты %s и %s не прошли проверку, %s дней разница",
["unknown_param"]="параметр %s неизвестен",
["unknown_error"]="неизвестная ошибка",
["tech_error"]="ошибка в функции %s",
["box_date"]="строка «%s» не является верной датой, пожалуйста, укажите дату в формате ГГГГ-ММ-ДД"
-- [""]="",
}
local tzs_names = {"ACDT","ACST","ACT","ADT","AEDT","AEST","AFT","AKDT","AKST",
"AMST","AMT","ART","AST","AST","AST","AST","AWDT","AWST","AZOST","AZT","BDT",
"BIOT","BIT","BOT","BRT","BST","BST","BTT","CAT","CCT","CDT","CEDT","CEST",
"CET","CHAST","CIST","CKT","CLST","CLT","COST","COT","CST","CST","CVT","CXT",
"CHST","DFT","EAST","EAT","ECT","ECT","EDT","EEDT","EEST","EET","EST","FJT",
"FKST","FKT","GALT","GET","GFT","GILT","GIT","GMT","GST","GYT","HADT","HAST",
"HKT","HMT","HST","IRKT","IRST","IST","IST","IST","JST","KRAT","KST","LHST",
"LINT","MAGT","MDT","MIT","MSD","MSK","MST","MST","MST","MUT","NDT","NFT",
"NPT","NST","NT","OMST","PDT","PETT","PHOT","PKT","PST","PST","RET","SAMT",
"SAST","SBT","SCT","SLT","SST","SST","TAHT","THA","UTC","UYST","UYT","VET",
"VLAT","WAT","WEDT","WEST","WET","YAKT","YEKT","Z","A","M","N","Y","MSK"}
local pattern = { -- для распознавания дат, переданных одним строчным параметром
{"(-?%d%d%d%d?)[-%.%s/\\](%d%d)[-%.%s/\\](%d%d)", ["order"] = {3,2,1} }, -- yyyy mm dd
{"(%d+)[-%.%s/\\](%d+)[-%.%s/\\](%d%d%d%d?)", ["order"] = {1,2,3} }, -- dd mm yyyy
{"(%d%d)[-%.%s/\\](%d%d%d%d?)", ["order"] = {2,3} }, -- mm yyyy
{"(%d%d%d%d?)[-%.%s/\\](%d%d)", ["order"] = {3,2} }, -- yyyy mm
{"(%d+)%s(%l+)%s(%d%d%d%d?)", ["order"] = {1,2,3} }, -- d mmm y
{"(%l+)%s(%d+),?%s(%d%d%d%d?)", ["order"] = {2,1,3} }, -- mmm d, y
{"(%l+)%s(%d%d%d%d?)", ["order"] = {2,3} }, -- mmm y
}
local time_units = {"year","month","day"} --не используется
--[[ local time_units = {"second", "minute", "hour",
"day_of_month", "day_of_week", "day_of_year",
"week", "month", "year", "year_of_century", "century"} ]]--
-- напоминание чтобы сделать более точные пересчёты - с часами / расчёт длительностей периодов
local mnlang = {"ru_G", "ru_N", "en", "en_S", "de", "fr"}
local month_lang = {
["ru_G"] = {"января","февраля","марта","апреля","мая","июня",
"июля","августа","сентября","октября","ноября","декабря"},
["ru_N"] = {"январь","февраль","март","апрель","май","июнь",
"июль","август","сентябрь","октябрь","ноябрь","декабрь"},
["en"] = {"january", "february", "march", "april", "may", "june",
"july", "august", "september", "october", "november", "december"},
["en_S"] = {"jan", "feb", "mar", "apr", "may", "jun",
"jul", "aug", "sep", "oct", "nov", "dec"},
["de"] = {"januar", "februar", "märz", "april", "mai", "juni",
"juli", "august", "september", "oktober", "november", "dezember"},
["fr"] = {"janvier", "février", "mars", "avril", "mai", "juin",
"juillet", "août", "septembre", "octobre", "novembre", "décembre"}
}
-- заполняется автоматически
local reverse_month_lang = {}
-- вспомогательная функция для обращения таблиц (смена ключей со значениями)
local reverse_table = function (strait_table)
local reversed_table = {}
for k,v in pairs(strait_table) do
reversed_table[v] = k
end
return reversed_table
end
-- запуск цикла по заполнению обратных таблиц, необходимых для распознавания дат
local filling_months = function (mnlang, month_lang)
for i=1, #mnlang do
reverse_month_lang[mnlang[i]] = reverse_table(month_lang[mnlang[i]])
end
end
-- 10) Блок общих функций
local function trim(str)
if not str then return nil
else return str:match'^()%s*$' and '' or str:match'^%s*(.*%S)'
end
end
local function purif(str)
if str == "" or str == nil then
return nil
elseif type(tonumber(str)) == "number" then
return math.floor(tonumber(str))
else
return nil
end
-- need .5 -- ,5 number format converter?
end
local function is(str)
if (not str) or (str == "") then return false
else return yesno(str,false)
end
end
local function init(num)
local output = {}
for i=1,num do
table.insert(output, {["year"]="", ["month"]="", ["day"]=""})
end
return unpack(output)
end
local function isyear(tbl)
if type(tbl) ~= 'table' then return false
elseif not tbl["year"] then return false
elseif type(tbl["year"]) == 'number' then return true
else return false
end
end
local function inbord(val, down, up)
return not (type(up) ~= "number" or type(down) ~= "number" or type(val) ~= "number" or up < down or val < down or val > up)
end
local function shallowcopy(orig)
local orig_type = type(orig)
local copy
if orig_type == 'table' then
copy = {}
for orig_key, orig_value in pairs(orig) do
copy[orig_key] = orig_value
end
else -- number, string, boolean, etc
copy = orig
end
return copy
end
local inlist = function ( var, list )
local n = #list
local inlist = false
for i=1,n do
if var == list[i] then inlist = true end
end
return inlist
end
-- 20) Блок общих проверочных функций, связанных с датами
local function unwarp(tbl)
if not tbl then return ""
elseif type(tbl) ~= "table" then return tbl
elseif (tbl.day or tbl.month or tbl.year) then
return (tbl.year or "?").."-"..(tbl.month or "?").."-"..(tbl.day or "?")
else return (tbl[3] or "?").."-"..(tbl[2] or "?").."-"..(tbl[1] or "?")
end
end
local function leap_year(y,jul)
if (not y) or (type(y) ~= "number")
then return false
elseif (y % 4) ~= 0
then return false
elseif not jul and (y % 100 == 0 and y % 400 ~= 0)
then return false
else return true
end
end
-- функция для вычисления последнего дня месяца для юлианского и григорианского календарей
local function month_end_day (month,year,is_julian)
local month_end_day = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} -- если не задан год, дата 29 февраля считается допустимой
if not month or type(month) ~= "number" or month < 1 or month > 12 then return nil
elseif month ~= 2 or not year then return month_end_day[month]
elseif month == 2 and (year % 4) == 0 and not ((not is_julian) and (year % 100 == 0 and year % 400 ~= 0)) then return 29
elseif month == 2 then return 28
else return nil -- в случае не целого значения входящих параметров или при иных непредусмотренных событиях
end
end
local function isdate ( chain , jul ) -- можно использовать для проверки таблиц с полями day, month, year
if not chain then return false
elseif (not type(chain) == "table")
or (not inbord(chain.year,-9999,9999))
or (not inbord(chain.month,1,12))
or (not inbord(chain.day,1,31))
or chain.day > monthd[chain.month]
-- or chain.year == 0
then return false
elseif chain.month == 2 and chain.day == 29 and not leap_year(chain.year,jul)
then return false
else return true end
-- check for other calendars needed?
end
local function ispartdate ( chain )
if not chain then return false
elseif not (type(chain) == "table") then return false
elseif (inbord(chain.year,-9999,9999)
or inbord(chain.month,1,12)
or inbord(chain.day,1,31)) then return true
else return false
end
-- partial date
-- more detailed check for 31.02.0000 needed
-- check for other calendars needed
end
-- from date1 to date2 in one year (beetwen jan-dec, dec-jan needed)
local function partdist(date1,date2)
local mont, dist = 0, 0
local d1d, d1m, d2d, d2m = (date1["day"] or ""), (date1["month"] or ""),(date2["day"] or ""), (date2["month"] or "")
if not (inbord(d1d,1,31) and inbord(d2d,1,31)) then return false end
-- нужна доп. проверка частичных дат на корректность
if (inbord(d1m,1,12) or inbord(d2m,1,12))
and (d1m == "" or d2m == "") then
mont = purif(date1["month"] or date2["month"])
d1m, d2m = mont, mont
end
-- mw.log("📏 day: " ..d1d .."->"..d2d.." month: ".. d1m.."->"..d2m )
if (inbord(d1m,1,12) and d1d <= monthd[d1m])
and (inbord(d2m,1,12) and d2d <= monthd[d2m]) then
if d2m == d1m
then dist = d2d - d1d
else dist = monthd[d1m] - d1d + d2d
end
return dist
else return math.huge
end
end
local function dmdist(d1,d2)
local p1,p2 = math.huge,math.huge
if not not partdist(d1,d2) then
p1=partdist(d1,d2)
end
if not not partdist(d2,d1) then
p1=partdist(d2,d1)
end
-- if (not p1) or (not p2) then
-- return (p1 or "") .. (p2 or "")
-- else
-- mw.log("d1, d2 = " .. undate(d1) .. ", " .. undate(d2))
return math.min(tonumber(partdist(d1,d2)) or math.huge,tonumber(partdist(d2,d1)) or math.huge)
-- end
end
-- 30) Блок функций для обработки ввода-вывода дат
local function undate(tbl)
if not tbl then return ""
else return (tbl.year or "").."-"..(tbl.month or "").."-"..(tbl.day or "")
end
end
-- функция для нормализации значений дат и перевода месяцев в числа
local function numerize(str)
if type(str) == "number" then
return math.floor(str)
elseif str == "" or str == nil or type(str) ~= "string" then
return nil
elseif type(tonumber(str)) == "number" then
return math.floor(tonumber(str))
else
for i=1, #mnlang do
if inlist(mw.ustring.lower(str),month_lang[mnlang[i]]) then
return reverse_month_lang[mnlang[i]][mw.ustring.lower(str)]
end
end
end
end
-- функция распознавания даты, переданной одной строкой
local function parse_date(date_string)
if type(date_string) ~= "string" or date_string == "" then return nil end
local out_date_str = {"","",""}
local error_data = {}
for i=1, #pattern do
local result_1, result_2, result_3 = mw.ustring.match(mw.ustring.lower(date_string),pattern[i][1])
if (result_1 or "") > "" then
out_date_str[pattern[i].order[1]] = result_1
out_date_str[pattern[i].order[2]] = result_2
if (pattern[i].order[3]) then out_date_str[pattern[i].order[3]] = result_3 end
-- mw.log("Паттерн " .. i .. ", строка: " .. date_string)
break
end
end
local date = {
["day"] =numerize(out_date_str[1]),
["month"]=numerize(out_date_str[2]),
["year"] =numerize(out_date_str[3])}
return date --, error_data
end
----[[ УСТАРЕЛО ]]----
local numstr2date = function(numstr)
local format = "Y-m-d"
local iso_date = mwlang:formatDate(format,numstr)
local y,m,d = string.match(iso_date, "(%d+)-(%d+)-(%d+)")
local dateout = {["year"]=purif(y), ["month"]=purif(m), ["day"]=purif(d)}
return dateout
end
--local numstr2date = function(numstr)
-- local nums = {}
-- local dateout = {}
-- for num in string.gmatch(numstr,"(%d+)") do
-- table.insert(nums,purif(num))
-- end
-- if #nums ~= 3 then error("В поле даты вместо трёх чисел с разделителями указано " .. #nums)
-- elseif not inbord(nums[2],1,12) then error("Месяц с номером " .. nums[2] .. " не найден")
-- elseif not inbord(nums[3],1,31) then
-- dateout = {["year"]=nums[3], ["month"]=nums[2], ["day"]=nums[1]}
-- elseif not inbord(nums[1],1,31) then
-- dateout = {["year"]=nums[1], ["month"]=nums[2], ["day"]=nums[3]}
-- elseif inbord(nums[1],1,31) then
-- dateout = {["year"]=nums[3], ["month"]=nums[2], ["day"]=nums[1]}
-- else
-- local mwlang = mw.getContentLanguage()
-- implement mwlang:formatDate(format,datein,true) here
-- return error("Не распознано " .. numstr .. " как дата")
-- end
-- return dateout
--end
local function year2lang(numyear,yearmark,wiki)
if not numyear then return "" end
if not yearmark then yearmark = "" end
local output = ""
local bcmark = " до н. э."
if numyear > 0 then bcmark = ""
else numyear = 1 - numyear end
if wiki then
-- output = tCon({'[[', numyear,' год',bcmark,'|', numyear,']]', " ", yearmark, " ", bcmark})
output = tCon({'[[', numyear,' год',bcmark,'|', trim(numyear .. " " .. yearmark .. " " .. bcmark), ']]'})
else
output = tCon({numyear, " ", yearmark, bcmark})
end
return trim(output)
end
local function day2lang(datein,wikidate,wiki,inner_brt)
-- if not isdate(wikidate) then wiki = false end
if not ispartdate(datein) then return "" end
local dm_separ, output = "", nil
if (not (not datein.day)) and (not (not datein.month)) then dm_separ = " " end
if (not datein.month) then datein.month = "" end
if (not datein.day) then datein.day = "" end
local monlan = monthlang[datein.month] or ""
if wiki and not inner_brt then
output = tCon({"[[", wikidate.day, " ", monthlang[wikidate.month] or "",
"|", (datein.day or ""), dm_separ, monlan, "]]"})
elseif wiki then
output = tCon({"[[", wikidate.day, " ", monthlang[wikidate.month] or "",
"|", (datein.day or ""), dm_separ, monlan})
else
output = tCon({datein.day, dm_separ, monlan})
end
return trim(output)
end
local function triple_txt2date(d,m,y)
-- добавить (args[1]:match("(%a+)") or "-") для нестандартной записи
-- mw.ustring.match((m or ""),"(%a+)")
local msg = ""
local year = purif((y or "-"):match("(%d+)"))
local month = purif(month_to_num[string.lower(mw.ustring.match((m or ""),"(%a+)"))])
local day = purif((d or "-"):match("(%d+)"))
if not month then
msg = category.incomplete_parameters
month = purif(month_to_num[string.lower(mw.ustring.match((d or ""),"(%a+)") or "-")])
end
if (not day) and ((purif(string.match(m or "","(%d+)") or "") or 32) <= (monthd[month] or 31)) then
msg = category.incomplete_parameters
day = purif(m:match("(%d+)") or "")
end
if not year then
msg = category.incomplete_parameters
year = purif(string.match(m or "","(%d+)") or "")
end
local dateout = {["year"]=year, ["month"]=month, ["day"]=day, ["msg"]=msg}
return dateout
end
local function glue(d1,m1,y1,d2,m2,y2)
if (not d1) and (not m1) and (not y1) and (not d2) and (not m2) and (not y2) then
return category.incomplete_parameters end
local gd,gm,gy,jd,jm,jy =
(d1 or ""),
(m1 or ""),
(y1 or ""),
(d2 or ""),
(m2 or ""),
(y2 or "")
--mw.log(tCon({gd,gm,gy,jd,jm,jy}))
local gm_sep = {" [["," год|","]]"}
if (not gy) or (gy == "") then gm_sep = {"","",""} end
return tCon({comment[1],trim(trim(jd .. " " .. jm) .. " " .. jy ),
comment[2]," ([[",trim(gd .. " " .. gm),"]]",gm_sep[1],(gy:match("(%d+)") or ""),
gm_sep[2],gy,gm_sep[3],")",category.incomplete_parameters})
end
-- добавить отображение без года
local function double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark)
local msg = ""
msg = (jdate.msg or "") .. (gdate.msg or "")
local cd = {}
local jd = shallowcopy(jdate)
local gd = shallowcopy(gdate)
local left = "("
local right = ")"
if sq_brts then
left = "["
right = "]"
end
if (not isdate(jdate,true)) then return error((jdate.day or "") .. "." .. (jdate.month or "") .."." .. (jdate.year or "") .. " неподходящая дата")
elseif (not isdate(gdate)) then return error((gdate.day or "") .. "." .. (gdate.month or "") .."." .. (gdate.year or "") .. " неподходящая дата") end
if jd.year == gd.year then
cd.year = gd.year
gd.year, jd.year = nil, nil
end
if jd.month == gd.month then
cd.month = gd.month
gd.month, jd.month = nil, nil
end
if (not not cd.month) and wm then
return tCon({comment[1] .. trim(day2lang(jd,jdate,false) .. " " .. year2lang(jd.year,yearmark,false)) .. comment[2],
trim(left .. day2lang(gd,gdate,wd,wm) .. " " .. year2lang(gd.year,yearmark,wy)) .. right,
day2lang(cd,gdate,false) .. "]]", trim(year2lang(cd.year,yearmark,wy)..msg)}, " ")
end
return tCon({comment[1] .. trim(day2lang(jd,jdate,false) .. " " .. year2lang(jd.year,yearmark,false)) .. comment[2],
trim(left .. day2lang(gd,gdate,wd) .. " " .. year2lang(gd.year,yearmark,wy)) .. right,
trim(day2lang(cd,gdate,false)), trim(year2lang(cd.year,yearmark,wy)..msg)}, " ")
end
-- 40) Блок функций для перевода дат с использованием [[Юлианская дата]]
local function gri2jd( datein )
if not isdate(datein) then return error((datein.day or "") .. "." .. (datein.month or "") .."." .. (datein.year or "") .. " неподходящая дата") end
local year = datein.year
local month = datein.month
local day = datein.day
-- jd calculation
local a = math.floor((14 - month)/12)
local y = year + 4800 - a
local m = month + 12*a - 3
local offset = math.floor(y/4) - math.floor(y/100) + math.floor(y/400) - 32045
local jd = day + math.floor((153*m + 2)/5) + 365*y + offset
-- jd validation
local low, high = -1931076.5, 5373557.49999
if not (low <= jd and jd <= high) then
return error((datein.day or "") .. "." .. (datein.month or "") .. "." .. (datein.year or "") .. " выходит за пределы разрешённого диапазона")
end
return jd
end
local function jd2jul( jd )
if type(jd) ~= "number" then return error("Промежуточная переменная " .. (jd or "") .. " не является числом") end
-- calendar date calculation
local c = jd + 32082
local d = math.floor((4*c + 3)/1461)
local e = c - math.floor(1461*d/4)
local m = math.floor((5*e + 2)/153)
local year_out = d - 4800 + math.floor(m/10)
local month_out = m + 3 - 12*math.floor(m/10)
local day_out = e - math.floor((153*m + 2)/5) + 1
-- output
local dateout = {["year"]=year_out, ["month"]=month_out, ["day"]=day_out}
return dateout
end
local function jul2jd( datein )
if not isdate(datein,true) then return error((datein.day or "") .. "." .. (datein.month or "") ..".".. (datein.year or "") .. " неподходящая дата") end
local year = datein.year
local month = datein.month
local day = datein.day
-- jd calculation
local a = math.floor((14 - month)/12)
local y = year + 4800 - a
local m = month + 12*a - 3
local offset = math.floor(y/4) - 32083
local jd = day + math.floor((153*m + 2)/5) + 365*y + offset
-- jd validation
local low, high = -1930999.5, 5373484.49999
if not (low <= jd and jd <= high) then
return error((datein.day or "") .. "." .. (datein.month or "") .."." .. (datein.year or "") .. " выходит за пределы разрешённого диапазона")
end
return jd
end
local function jd2gri( jd )
if type(jd) ~= "number" then return error("Промежуточная переменная " .. (jd or "") .. " не является числом") end
-- calendar date calculation
local a = jd + 32044
local b = math.floor((4*a + 3) / 146097)
local c = a - math.floor(146097*b/4)
local d = math.floor((4*c+3)/1461)
local e = c - math.floor(1461*d/4)
local m = math.floor((5*e+2)/153)
local day_out = e - math.floor((153*m+2)/5)+1
local month_out = m + 3 - 12*math.floor(m/10)
local year_out = 100*b + d - 4800 + math.floor(m/10)
-- output
local dateout = {["year"]=year_out, ["month"]=month_out, ["day"]=day_out}
return dateout
end
local function astroyear(num, bc)
if not num then return error()
elseif type(num) ~= "number" then return error()
end
if num < 1 then return num end
if not bc then return num
else return 1 - num
end
end
local function recalc(datein,calend)
if inlist(calend,params[1]) then
return jd2jul(gri2jd(datein)), datein
elseif inlist(calend,params[2]) then
return datein, jd2gri(jul2jd(datein))
else error("Параметр " .. (calend or "") .. " не опознан, разрешённые: " .. tCon(params[1]," ") .. " и " .. tCon(params[2]," "))
end
end
-- 50) Функции для обработки UTC
local function utc(str,margin)
local d = 1
local dchar = "+"
local beginning = "[[UTC"
local ending = "]]"
local cat = ""
local nums = {}
local hmarg, timedec = 0, 0
local mmarg = "00"
local output = ""
-- checking type of input
if not margin then margin = 0
elseif type(tonumber(margin)) ~= 'number' then
output = "Can't shift by " .. margin
error(output)
end
if type(str) ~= 'string' then
error("Нет входящей строки")
elseif str:byte(1) == 43 then
elseif inbord(str:byte(1),48,57) then cat = "[[Категория:Википедия:Ошибка в часовом поясе НП]]"
elseif str:byte(1) == 45 or string.sub(str,1,3) == "−" or string.sub(str,1,1)=="-" then d = -1
else
error(string.char(str:byte(1)) .. " недопустимый первый символ")
end
-- parsing input
for num in string.gmatch(str,"(%d+)") do
table.insert(nums,purif(num))
end
if #nums > 2 then error("Ожидается всего 2 числа, а не " .. #nums)
elseif #nums == 0 then error("Необходимо что-то ввести")
elseif #nums == 1 then
if inbord(nums[1],0,14) then timedec = d*nums[1] + margin
else error("Только часы от -14 до 14") end
elseif #nums == 2 then
if not inbord(nums[1],0,14) then error("Только часы от -14 до 14")
elseif not inbord(nums[2],0,59) then error("Минуты только от 0 до 59")
else
timedec = d*(nums[1] + nums[2]/60) + margin
end
end
if tonumber(timedec) == purif(timedec) then hmarg = timedec
else
local h, m = math.modf(math.abs(timedec))
hmarg = h
mmarg = math.floor(m*60)
end
if timedec == 0 then
dchar = "±"
elseif timedec > 0 then
elseif timedec < 0 then
dchar = "−"
end
-- output
output = beginning .. dchar .. math.abs(hmarg) .. ":" .. string.format("%02d",mmarg) .. ending .. cat
return output
end
-- 60) Блок функций ввода-вывода
function p.NthDay( frame )
local args = getArgs(frame, { frameOnly = true })
local num, wday, mont, yea, format =
purif(args[1]), purif(args[2]), purif(args[3]), purif(args[4]), args[5]
if not format then format = "%d.%m.%y" end
if not inbord(num,-5,5) then
return error("The number must be between -5 and 5")
elseif num == 0 then
return error("The number must not be zero") end
if not inbord(wday,0,6) then
return error("The day of the week must be between 0 and 6") end
if not inbord(mont,1,12) then
return error("The month must be between 1 and 12") end
if not inbord(yea,0,9999) then
return error("Wrong year number") end
if inbord(num,1,5) then
local m_start = os.time{year=yea, month=mont, day=1, hour=0}
local m_wds = tonumber(os.date("%w", m_start))
local start_shift = (
(num - bool_to_number[wday >= m_wds]) * 7
- (m_wds - wday)
) * 24 * 60 * 60
local tim = m_start + start_shift
if tonumber(os.date("%m", tim)) == mont then
return (os.date(format, tim))
else
return (err)
end
elseif inbord(num,-5,-1) then
local m_end = os.time{year = yea, month = mont + 1, day = 1, hour = 0} - 24 * 60 * 60
local m_wde = tonumber(os.date("%w", m_end))
local end_shift = ((math.abs(num + 1) + bool_to_number[wday > m_wde]) * 7
+ (m_wde - wday)) * 24 * 60 * 60
local tim = m_end - end_shift
if tonumber(os.date("%m", tim)) == mont then
return (os.date(format, tim))
else
return (err)
end
end
end
-- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"12 декабря 2020"}})
-- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"1.2.1602"}})
-- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"12.12.2021"}})
-- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"2021.12.12"}})
function p.ToIso( frame )
local args = getArgs(frame, { frameOnly = true })
local datein = args[1]
-- инициализация, заполнение обратных таблиц, копирование параметров
filling_months(mnlang, month_lang)
-- парсинг входящей даты по шаблону
local date = parse_date(datein)
if not (type(date.year) == 'number') then
return ("Wrong year: " .. unwarp(date))
end
if not (1 <= date.month and date.month <= 12) then
return ("Wrong month: " .. unwarp(date))
end
if not date.day or not (1 <= date.day and date.day <= month_end_day(date.month,date.year)) then
return ("Wrong day: " .. unwarp(date))
end
local timedate = os.time{year=date.year, month=date.month, day=date.day}
local date = os.date("%Y-%m-%d", timedate)
return date
end
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12 декабря 2020"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"1.2.1602"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"декабрь 2020"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12-2020"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12.12.2021"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"2021.12.12"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"2021.11"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"11.2021"}})
function p.BoxDate( frame )
local args = getArgs(frame, { frameOnly = true })
local txtDateIn, strFormat = args[1], args[2]
local txtDateOut, date, status = p.bxDate(txtDateIn, strFormat, params)
if status.brk then
return error(status.errorText)
else
return txtDateOut
end
end
function p.bxDate( txtDateIn , strFormat, params ) -- к отладке
local txtDateOut, date, status = "", {}, {brk = false, errorCat = "", errorText = ""}
strFormat = strFormat or "j xg Y"
-- заглушка - таблица параметров на будущее
params = params or {}
if not txtDateIn then
status.errorText = e.no_data
status.errorCat = category.no_parameters
status.brk = true
else
-- заполнение служебных таблиц
filling_months(mnlang, month_lang)
end
if not status.brk then
-- парсинг входящей даты по шаблону
date = parse_date(txtDateIn)
-- заменить сообщения об ошибках на списочные
if not (date.year and type(date.year) == 'number') then
status.errorText = string.format(e.box_date,txtDateIn)
status.errorCat = category.incomplete_parameters
status.brk = true
end
if not inbord(date.month,1,12) then
status.errorText = string.format(e.box_date,txtDateIn)
status.errorCat = category.incomplete_parameters
status.brk = true
end
if not date.day and string.find(strFormat,"[dDjlNwzW]") then
strFormat = trim(string.gsub(string.gsub(strFormat,"xg","F"),"[dDjlNwzW]",""))
elseif not date.day then
elseif not inbord(date.day,1,month_end_day(date.month,date.year)) then
status.errorText = string.format(e.box_date,txtDateIn)
status.errorCat = category.incomplete_parameters
status.brk = true
end
end
if not status.brk then
txtDateOut = mwlang:formatDate(strFormat,tCon({date.year,date.month,date.day},"-"),true)
end
return txtDateOut, date, status
end
function p.ToDate( frame ) -- возможно неиспользуемая
local args = getArgs(frame, { frameOnly = true })
local mwlang = mw.getContentLanguage()
local datein = args[1]
local format = "j xg Y"
if not string.match(datein, "%p") then return datein
elseif not args[2] then
else format = args[2]
end
return mwlang:formatDate(format,datein,true)
end
-- =p.unitime(mw.getCurrentFrame():newChild{title="smth",args={"−1:30","1"}})
function p.unitime( frame )
local args = getArgs(frame, { frameOnly = true })
local DST = 0
if not args[2] then
else DST = 1 end
local utcin = ""
local input = args[1]
if not input then return "" end
if inlist(input:upper(),tzs_names) then
utcin = known_tzs[input:upper()]
elseif (string.sub(input:upper(),1,3) == 'UTC') and (string.len(input) < 10) then
utcin = string.sub(input,4)
else
if string.sub(input,1,1) == '['
or string.sub(input,1,1) == '{'
or string.sub(input,1,1):upper() == 'U'
or string.sub(input,1,1):upper() == 'M' then
return input
-- elseif not string.find(string.upper(string.sub(input,1,1)),"[\65-\90]") or
-- not string.find(string.upper(string.sub(input,1,1)),"[\192-\223]") then
-- return input
else utcin = input end
end
-- elseif string.sub(input,1,3) ~= "−" then utcin = input
-- or not (not input:find("[А-я]")) при наличии в строке юникода не работает
local output = ""
if DST == 0 then output = utc(utcin)
else output = utc(utcin) .. ", [[летнее время|летом]] " .. utc(utcin,DST)
end
return output
end
-- УСТАРЕЛО
-- =p.OldDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020","ю",["bc"]="1",["wd"]="1",["wy"]="1",["sq_brts"]="1",["yearmark"]="г."}})
function p.OldDate( frame )
local args = getArgs(frame, { frameOnly = true })
if not args[1] then return err end
local gdate, jdate = {}, {}
local strin = args[1]
local cal = args[2]:lower() or "г"
local bc = is(args["bc"])
local wd = is(args["wd"])
local wm = is(args["wm"])
local wy = is(args["wy"])
if not wd then wm = false end
local sq_brts = is(args["sq_brts"])
local yearmark = "года"
if yesno(args["yearmark"]) then
elseif yesno(args["yearmark"]) == false then yearmark = ""
else yearmark = trim(args["yearmark"]) or "года" end
-- local infocard = is(args["infocard"])
-- local catName = args["catName"] or false
local datein = numstr2date(strin)
datein.year = astroyear(datein.year, bc)
jdate, gdate = recalc(datein,cal)
return double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark)
end
-- =p.NewDate(mw.getCurrentFrame():newChild{title="Salt",args={"2020-02-20"}})
-- =p.NewDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020","ю",["bc"]="1",["wd"]="1",["wy"]="1",["sq_brts"]="1",["yearmark"]="г."}})
-- =p.NewDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020",["bc"]="0",["wd"]="1",["wy"]="1",["sq_brts"]="0",["yearmark"]=""}})
function p.NewDate( frame )
local args = getArgs(frame, { frameOnly = true })
if not args[1] then return err end
local strin = args[1]
local year, month, day
if not not strin:match( "(-?%d%d%d%d%d)-(%d%d)-(%d%d)" ) then
year, month, day = strin:match( "(-?%d%d%d%d%d)-(%d%d)-(%d%d)" )
elseif not not strin:match( "(-?%d+)-(%d+)-(%d+)" ) then
year, month, day = strin:match( "(-?%d+)-(%d+)-(%d+)" )
elseif not not strin:match( "(%d%d)%.(%d%d)%.(-?%d%d%d%d%d)" ) then
day, month, year = strin:match( "(%d%d)%.(%d%d)%.(-?%d%d%d%d%d)" )
elseif not not strin:match( "(%d+)%.(%d+)%.(-?%d+)" ) then
day, month, year = strin:match( "(%d+)%.(%d+)%.(-?%d+)" )
end
if not year then return error(args[1] .. " не подходит под форматы yyyy-mm-dd или dd.mm.yyyy")
end
local cal = "г"
if (not args[2]) or (args[2] == "") then cal = "г"
else cal = args[2]:lower() end
local bc,wd,wm,wy,sq_brts =
is(args["bc"]),
is(args["wd"]),
is(args["wd"]) and is(args["wm"]),
is(args["wy"]),
is(args["sq_brts"])
year = astroyear(purif(year),bc)
local datein = {["year"]=purif(year), ["month"]=purif(month), ["day"]=purif(day)}
local jdate, gdate = recalc(datein,cal)
local yearmark = "года"
local ym = args["yearmark"] or ""
if yesno(ym) then
elseif yesno(ym) == false then yearmark = ""
else
if not not ym:match("(%d+)") then
error("Цифры в обозначении года: " .. ym)
else yearmark = trim(ym) or "года" end
end
return double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark)
end
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"3","июня",nil,"21","мая"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28 августа","","1916 года","15"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"3","июня","1900","21","мая"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"6","июня","1889 год","25","мая"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28","ноября","1917","15"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28 августа","nil","1916 года","15"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"4","января","1915","22","декабря","1914 года"}})
-- {{OldStyleDate|день (НС)|месяц (НС)|год (НС)|день (СС)|месяц (СС)|год (СС)}}
function p.Test( frame )
local args = getArgs(frame, { frameOnly = true })
-- необходима проверка и замена nil на " "
--[[mw.log((args[1] or "") .. " " ..
(args[2] or "") .. " " ..
(args[3] or "") .. " " ..
(args[4] or "") .. " " ..
(args[5] or "") .. " " ..
(args[6] or "")) ]]--
local ingdate = triple_txt2date(args[1],args[2],args[3])
local injdate = triple_txt2date(args[4],args[5],args[6])
local j1date, g1date, j2date, g2date = init(4)
mw.log("ingdate-".. (undate(ingdate) or ""))
mw.log("injdate-".. (undate(injdate) or ""))
local bc,wd,wm,wy,sq_brts,ny =
is(args["bc"]),
is(args["wd"]),
is(args["wd"]) and is(args["wm"]),
is(args["wy"]),
is(args["sq_brts"]),
is(args["ny"])
-- подавление формата для локальных тестов
local wd, wm, wy = true, true, true
local yearmark = "года"
local ym = args["yearmark"] or ((mw.ustring.match((args[3] or ""),"(%a+)") or mw.ustring.match((args[6] or ""),"(%a+)")) or "")
-- mw.log("ym " .. ym)
if yesno(ym) then
elseif yesno(ym) == false then yearmark = ""
else
if not not ym:match("(%d+)") then
error("Цифры в обозначении года: " .. ym)
else yearmark = trim(ym) or "года" end
end
if isdate(ingdate) or isdate(injdate) then
if isdate(ingdate) then
j1date, g1date = recalc(ingdate,"g")
ingdate["full"] = true
end
if isdate(injdate) then
j2date, g2date = recalc(injdate,"j")
injdate["full"] = true
end
if ispartdate(ingdate) and ispartdate(injdate) then
mw.log("📏 " .. dmdist(ingdate,injdate))
mw.log("📏 " .. dmdist(j1date,g1date))
mw.log("📏 " .. dmdist(j2date,g2date))
mw.log("📏 " .. dmdist(ingdate,g1date))
mw.log("📏 " .. dmdist(injdate,j2date))
end
end
if ny then
if isyear(j1date) then
else j1date["year"] = "" end
if isyear(j2date) == nil then
else j2date["year"] = "" end
if isyear(g1date) == nil then
else g1date["year"] = "" end
if isyear(g2date) == nil then
else g2date["year"] = "" end
end
if (isdate(j1date) and isdate(g1date) and isdate(j2date) and isdate(g2date)) then
if ((j1date.year == j2date.year)
and (j1date.month == j2date.month)
and (j1date.day == j2date.day)) then
return double_couple(j1date, g1date, wd, wm, wy, sq_brts, yearmark)
else
mw.log("📏 " .. (tostring(dmdist(ingdate,injdate)) or ""))
return glue(args[1],args[2],args[3],args[4],args[5],args[6])
-- категория (предположительная разница в днях) и частичный вывод
end
elseif isdate(j1date) and isdate(g1date) then
return double_couple(j1date, g1date, wd, wm, wy, sq_brts, yearmark) -- категория плюс частичная проверка
elseif isdate(j2date) and isdate(g2date) then
return double_couple(j2date, g2date, wd, wm, wy, sq_brts, yearmark) -- категория плюс частичная проверка
elseif (ispartdate(ingdate) and ispartdate(injdate)) then
mw.log("ingdate ".. (undate(ingdate) or ""))
mw.log("injdate ".. (undate(injdate) or ""))
mw.log("j1date " .. (undate(j1date ) or ""))
mw.log("j2date " .. (undate(j2date ) or ""))
mw.log("g1date " .. (undate(g1date ) or ""))
mw.log("g2date " .. (undate(g2date ) or ""))
mw.log("📏 " .. (tostring(partdist(ingdate,injdate)) or "").. " — " .. (tostring(partdist(injdate,ingdate)) or ""))
return glue(args[1],args[2],args[3],args[4],args[5],args[6])
-- частичный или полный вывод, категория
else
mw.log("ingdate ".. (undate(ingdate) or ""))
mw.log("injdate ".. (undate(injdate) or ""))
mw.log("j1date " .. (undate(j1date ) or ""))
mw.log("j2date " .. (undate(j2date ) or ""))
mw.log("g1date " .. (undate(g1date ) or ""))
mw.log("g2date " .. (undate(g2date ) or ""))
return err .. category.incomplete_parameters
end
end
return p
a4a91f134ad3e3b246b3a6681a4ae438da766df4
Модуль:Message box/configuration
828
67
107
106
2024-08-09T16:02:48Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Message box configuration --
-- --
-- This module contains configuration data for [[Module:Message box]]. --
--------------------------------------------------------------------------------
return {
ambox = {
types = {
speedy = {
class = 'ambox-speedy',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'ambox-delete',
image = 'Stop hand nuvola.svg'
},
content = {
class = 'ambox-content',
image = 'Emblem-important.svg'
},
style = {
class = 'ambox-style',
image = 'Broom_icon.svg'
},
move = {
class = 'ambox-move',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'ambox-protection',
image = 'Padlock-silver-medium.svg'
},
notice = {
class = 'ambox-notice',
image = 'Information.svg'
},
good = {
class = 'ambox-good',
image = 'Green star boxed.svg'
},
serious = {
class = 'ambox-serious',
image = 'Stop hand nuvola.svg'
},
merge = {
class = 'ambox-merge',
image = 'Merge-split-transwiki default.svg'
},
discussion = {
class = 'ambox-discussion',
image = 'Nuvola apps ksirc.png'
}
},
default = 'notice',
allowBlankParams = {'talk', 'sect', 'date', 'issue', 'fix', 'subst', 'hidden', 'image'},
allowSmall = true,
smallParam = 'left',
smallClass = 'mbox-small-left',
substCheck = true,
classes = {'metadata', 'ambox'},
imageEmptyCell = true,
imageCheckBlank = true,
imageSmallSize = '20x20px',
imageCellDiv = true,
useCollapsibleTextFields = true,
imageRightNone = true,
sectionDefault = 'статья',
allowMainspaceCategories = true,
templateCategory = 'Шаблоны:Шаблоны-сообщения для статей',
templateCategoryRequireName = true,
templateErrorCategory = 'Шаблоны:Шаблоны-сообщения для статей с пропущенными параметрами',
templateErrorParamsToCheck = {'issue', 'fix'},
removalNotice = '[[Help:Maintenance template removal|Learn how and when to remove this template message]]',
templatestyles = 'Module:Message box/ambox.css',
},
cmbox = {
types = {
speedy = {
class = 'cmbox-speedy notheme',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'cmbox-delete notheme',
image = 'Ambox warning pn.svg'
},
content = {
class = 'cmbox-content notheme',
image = 'Ambox important.svg'
},
style = {
class = 'cmbox-style notheme',
image = 'Edit-clear.svg'
},
move = {
class = 'cmbox-move notheme',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'cmbox-protection notheme',
image = 'Padlock-silver-medium.svg'
},
notice = {
class = 'cmbox-notice notheme',
image = 'Information icon4.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'cmbox'},
imageEmptyCell = true,
useCollapsibleTextFields = true,
templatestyles = 'Module:Message box/cmbox.css',
},
fmbox = {
types = {
warning = {
class = 'fmbox-warning',
image = 'Ambox warning pn.svg'
},
editnotice = {
class = 'fmbox-editnotice',
image = 'Information icon4.svg'
},
system = {
class = 'fmbox-system',
image = 'Information icon4.svg'
}
},
default = 'system',
showInvalidTypeError = true,
classes = {'fmbox'},
imageEmptyCell = false,
imageRightNone = false,
useCollapsibleTextFields = true,
templatestyles = 'Module:Message box/fmbox.css',
},
imbox = {
types = {
speedy = {
class = 'imbox-speedy',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'imbox-delete',
image = 'Ambox warning pn.svg'
},
content = {
class = 'imbox-content',
image = 'Ambox important.svg'
},
style = {
class = 'imbox-style',
image = 'Edit-clear.svg'
},
move = {
class = 'imbox-move',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'imbox-protection',
image = 'Padlock-silver-medium.svg'
},
license = {
class = 'imbox-license licensetpl',
image = 'Imbox license.png' -- @todo We need an SVG version of this
},
featured = {
class = 'imbox-featured',
image = 'Cscr-featured.svg'
},
notice = {
class = 'imbox-notice',
image = 'Information icon4.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'imbox'},
imageEmptyCell = true,
below = true,
useCollapsibleTextFields = true,
templateCategory = 'Шаблоны:Шаблоны-сообщения для файлов',
templatestyles = 'Module:Message box/imbox.css',
},
ombox = {
types = {
speedy = {
class = 'ombox-speedy',
image = 'OOjs UI icon alert-destructive.svg'
},
delete = {
class = 'ombox-delete',
image = 'OOjs UI icon alert-destructive.svg'
},
content = {
class = 'ombox-content',
image = 'OOjs UI icon notice-warning.svg'
},
style = {
class = 'ombox-style',
image = 'Edit-clear.svg'
},
move = {
class = 'ombox-move',
image = 'Imbox move.png'
},
protection = {
class = 'ombox-protection',
image = 'Imbox protection.png'
},
notice = {
class = 'ombox-notice',
image = 'OOjs UI icon info-progressive.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'ombox'},
allowSmall = true,
imageEmptyCell = true,
imageRightNone = true,
useCollapsibleTextFields = true,
templatestyles = 'Module:Message box/ombox.css',
},
tmbox = {
types = {
speedy = {
class = 'tmbox-speedy notheme',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'tmbox-delete notheme',
image = 'Ambox warning pn.svg'
},
content = {
class = 'tmbox-content notheme',
image = 'Ambox important.svg'
},
style = {
class = 'tmbox-style notheme',
image = 'Edit-clear.svg'
},
move = {
class = 'tmbox-move notheme',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'tmbox-protection notheme',
image = 'Padlock-silver-medium.svg'
},
notice = {
class = 'tmbox-notice notheme',
image = 'Information icon4.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'tmbox'},
allowSmall = true,
imageRightNone = true,
imageEmptyCell = true,
imageEmptyCellStyle = true,
useCollapsibleTextFields = true,
templateCategory = 'Шаблоны:Шаблоны-сообщения для страниц обсуждений',
templatestyles = 'Module:Message box/tmbox.css',
}
}
dd71cfc9b05d5244df926bfe86dfdb7ad0e0ff85
Модуль:Message box/ombox.css
828
68
109
108
2024-08-09T16:04:02Z
DuOfOrl
5
1 версия импортирована
sanitized-css
text/css
/* Скопировано из [[:en:Module:Message box/ombox.css]] */
.ombox {
margin: 4px 0;
border-collapse: collapse;
border: 1px solid var(--border-color-base, #a2a9b1); /* Default "notice" gray */
background-color: var(--background-color-neutral-subtle, #f8f9fa);
box-sizing: border-box;
}
/* For the "small=yes" option. */
.ombox.mbox-small {
font-size: 88%;
line-height: 1.25em;
}
.ombox-speedy {
border: 2px solid var(--border-color-error, #b32424); /* Red */
background-color: var(--background-color-error-subtle, #fee7e6); /* Pink */
}
.ombox-delete {
border: 2px solid var(--background-color-error--active, #b32424); /* Red */
}
.ombox-content {
border: 1px solid #f28500; /* Orange */
}
.ombox-style {
border: 1px solid #fc3; /* Yellow */
}
.ombox-move {
border: 1px solid #9932cc; /* Purple */
}
.ombox-protection {
border: 2px solid var(--border-color-base, #a2a9b1); /* Gray-gold */
}
.ombox .mbox-text {
border: none;
/* @noflip */
padding: 0.25em 0.9em;
width: 100%;
}
.ombox .mbox-image {
border: none;
/* @noflip */
padding: 2px 0 2px 0.9em;
text-align: center;
}
.ombox .mbox-imageright {
border: none;
/* @noflip */
padding: 2px 0.9em 2px 0;
text-align: center;
}
/* An empty narrow cell */
.ombox .mbox-empty-cell {
border: none;
padding: 0;
width: 1px;
}
.ombox .mbox-invalid-type {
text-align: center;
}
/* Хак, TODO: посмотреть, как оно на самом деле работает */
.ombox .mbox-textsmall-div {
font-size: 90%;
}
@media (min-width: 720px) {
.ombox {
margin: 4px 10%;
}
.ombox.mbox-small {
/* @noflip */
clear: right;
/* @noflip */
float: right;
/* @noflip */
margin: 4px 0 4px 1em;
width: 238px;
}
/* Стили нотификаций для ноутбуков */
@media (max-width: 1366px) {
.ombox {
margin-left: 6%;
margin-right: 6%;
}
}
}
/* [[Категория:Модули:Подстраницы CSS]] */
6627874170f6674674bfa5796b2f7dfb6698cd81
Модуль:Category handler/data
828
69
111
110
2024-08-09T16:05:04Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
-- This module assembles data to be passed to [[Module:Category handler]] using
-- mw.loadData. This includes the configuration data and whether the current
-- page matches the title blacklist.
local data = require('Module:Category handler/config')
local mShared = require('Module:Category handler/shared')
local blacklist = require('Module:Category handler/blacklist')
local title = mw.title.getCurrentTitle()
data.currentTitleMatchesBlacklist = mShared.matchesBlacklist(
title.prefixedText,
blacklist
)
data.currentTitleNamespaceParameters = mShared.getNamespaceParameters(
title,
mShared.getParamMappings()
)
return data
abbc68048ff698e88dda06b64ecf384bbf583120
Модуль:Category handler/config
828
70
113
112
2024-08-09T16:06:41Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
--------------------------------------------------------------------------------
-- [[Module:Category handler]] configuration data --
-- Language-specific parameter names and values can be set here. --
-- For blacklist config, see [[Module:Category handler/blacklist]]. --
--------------------------------------------------------------------------------
local cfg = {} -- Don't edit this line.
--------------------------------------------------------------------------------
-- Start configuration data --
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Parameter names --
-- These configuration items specify custom parameter names. --
-- To add one extra name, you can use this format: --
-- --
-- foo = 'parameter name', --
-- --
-- To add multiple names, you can use this format: --
-- --
-- foo = {'parameter name 1', 'parameter name 2', 'parameter name 3'}, --
--------------------------------------------------------------------------------
cfg.parameters = {
-- The nocat and categories parameter suppress
-- categorisation. They are used with Module:Yesno, and work as follows:
--
-- cfg.nocat:
-- Result of yesno() Effect
-- true Categorisation is suppressed
-- false Categorisation is allowed, and
-- the blacklist check is skipped
-- nil Categorisation is allowed
--
-- cfg.categories:
-- Result of yesno() Effect
-- true Categorisation is allowed, and
-- the blacklist check is skipped
-- false Categorisation is suppressed
-- nil Categorisation is allowed
nocat = 'nocat',
categories = 'categories',
-- The parameter name for the legacy "category2" parameter. This skips the
-- blacklist if set to the cfg.category2Yes value, and suppresses
-- categorisation if present but equal to anything other than
-- cfg.category2Yes or cfg.category2Negative.
category2 = 'category2',
-- cfg.subpage is the parameter name to specify how to behave on subpages.
subpage = 'subpage',
-- The parameter for data to return in all namespaces.
all = 'all',
-- The parameter name for data to return if no data is specified for the
-- namespace that is detected.
other = 'other',
-- The parameter name used to specify a page other than the current page;
-- used for testing and demonstration.
demopage = 'page',
}
--------------------------------------------------------------------------------
-- Parameter values --
-- These are set values that can be used with certain parameters. Only one --
-- value can be specified, like this: --
-- --
-- cfg.foo = 'value name' -- --
--------------------------------------------------------------------------------
-- The following settings are used with the cfg.category2 parameter. Setting
-- cfg.category2 to cfg.category2Yes skips the blacklist, and if cfg.category2
-- is present but equal to anything other than cfg.category2Yes or
-- cfg.category2Negative then it supresses cateogrisation.
cfg.category2Yes = 'yes'
cfg.category2Negative = '¬'
-- The following settings are used with the cfg.subpage parameter.
-- cfg.subpageNo is the value to specify to not categorise on subpages;
-- cfg.subpageOnly is the value to specify to only categorise on subpages.
cfg.subpageNo = 'no'
cfg.subpageOnly = 'only'
--------------------------------------------------------------------------------
-- Default namespaces --
-- This is a table of namespaces to categorise by default. The keys are the --
-- namespace numbers. --
--------------------------------------------------------------------------------
cfg.defaultNamespaces = {
[ 0] = true, -- main
[ 6] = true, -- file
[ 12] = true, -- help
[ 14] = true, -- category
[100] = true, -- portal
[108] = true, -- book
}
--------------------------------------------------------------------------------
-- Wrappers --
-- This is a wrapper template or a list of wrapper templates to be passed to --
-- [[Module:Arguments]]. --
--------------------------------------------------------------------------------
cfg.wrappers = 'Template:Category handler'
--------------------------------------------------------------------------------
-- End configuration data --
--------------------------------------------------------------------------------
return cfg -- Don't edit this line.
373cd107b13a5b00e6a1b7e66a749f12502c849d
Шаблон:Tag
10
72
117
116
2024-08-09T16:09:01Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{#ifeq: {{{style|}}} | regular | <templatestyles src="Модуль:Template call code/styles.css" /> }}<{{#ifeq: {{{style|}}} | regular | span | code }} class="{{#ifeq: {{{wrap|}}} | yes | wrap | nowrap }}" style="{{#switch: {{{style|}}}
| plain = border:none; background:transparent;
| regular =
| {{{style|}}}
}}"><!--
Opening tag
-->{{#switch: {{#if: {{{2|}}} | {{{2|}}} | pair }}
|c|close =
|s|single
|o|open
|p|pair = {{#ifeq: {{{1|tag}}}
| !--
| {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak"><!--</span> | <!-- }}
| {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak"><</span> | < }}{{{1|tag}}}{{#if: {{{params|{{{p|}}}}}} |  {{{params|{{{p|}}}}}} }}
}}
}}<!--
Content between tags
-->{{#switch: {{#if: {{{2|}}} | {{{2|}}} | pair }}
|c|close = {{{content|{{{c|}}}}}}
|s|single =  {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">/></span> | /> }}
|o|open = {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">></span> | > }}{{{content|{{{c|}}}}}}
|p|pair = {{#ifeq: {{{1|tag}}} | !-- || {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">></span> | > }} }}{{{content|{{{c|}}}}}}
}}<!--
Closing tag
-->{{#switch: {{#if: {{{2|}}} | {{{2|}}} | pair }}
|s|single
|o|open =
|c|close
|p|pair = {{#ifeq: {{{1|tag}}}
| !--
| {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">--></span> | --> }}
| {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak"></</span>{{{1|tag}}}<span class="ts-templateCallCode-weak">></span> | </{{{1|tag}}}> }}
}}
}}<!--
--></{{#ifeq: {{{style|}}} | regular | span | code }}><noinclude>{{doc}}</noinclude>
2818843691a5275eaf013ee7cc1ac4b87c34f392
Шаблон:Big
10
73
119
118
2024-08-09T16:10:05Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<span style="font-size:120%;">{{{1}}}</span><noinclude>
{{documentation}}
<!-- PLEASE ADD CATEGORIES TO THE /doc SUBPAGE, THANKS -->
</noinclude>
233a0192f59d7a0c6fef6b818e8d1c96d48295d2
Модуль:Category handler/shared
828
74
121
120
2024-08-09T16:14:00Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
-- This module contains shared functions used by [[Module:Category handler]]
-- and its submodules.
local p = {}
function p.matchesBlacklist(page, blacklist)
for i, pattern in ipairs(blacklist) do
local match = mw.ustring.match(page, pattern)
if match then
return true
end
end
return false
end
function p.getParamMappings(useLoadData)
local dataPage = 'Module:Namespace detect/data'
if useLoadData then
return mw.loadData(dataPage).mappings
else
return require(dataPage).mappings
end
end
function p.getNamespaceParameters(titleObj, mappings)
-- We don't use title.nsText for the namespace name because it adds
-- underscores.
local mappingsKey
if titleObj.isTalkPage then
mappingsKey = 'talk'
else
mappingsKey = mw.site.namespaces[titleObj.namespace].name
end
mappingsKey = mw.ustring.lower(mappingsKey)
return mappings[mappingsKey] or {}
end
return p
d2d5de1a031e6ce97c242cbfa8afe7a92cb9eca5
Модуль:Category handler/blacklist
828
75
123
122
2024-08-09T16:16:12Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
-- This module contains the blacklist used by [[Module:Category handler]].
-- Pages that match Lua patterns in this list will not be categorised unless
-- categorisation is explicitly requested.
return {
'^Main Page$', -- don't categorise the main page.
-- Don't categorise the following pages or their subpages.
-- "%f[/\0]" matches if the next character is "/" or the end of the string.
'^Wikipedia:Cascade%-protected items%f[/\0]',
'^User:UBX%f[/\0]', -- The userbox "template" space.
'^User talk:UBX%f[/\0]',
-- Don't categorise subpages of these pages, but allow
-- categorisation of the base page.
'^Wikipedia:Template messages/.*$',
'/[aA]rchive' -- Don't categorise archives.
}
c84948ad9808d5d323408d5d10d5652f748a0550
Модуль:Namespace detect/data
828
76
125
124
2024-08-09T16:32:35Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Namespace detect data --
-- This module holds data for [[Module:Namespace detect]] to be loaded per --
-- page, rather than per #invoke, for performance reasons. --
--------------------------------------------------------------------------------
local cfg = require('Module:Namespace detect/config')
local function addKey(t, key, defaultKey)
if key ~= defaultKey then
t[#t + 1] = key
end
end
-- Get a table of parameters to query for each default parameter name.
-- This allows wikis to customise parameter names in the cfg table while
-- ensuring that default parameter names will always work. The cfg table
-- values can be added as a string, or as an array of strings.
local defaultKeys = {
'main',
'talk',
'other',
'subjectns',
'demospace',
'demopage'
}
local argKeys = {}
for i, defaultKey in ipairs(defaultKeys) do
argKeys[defaultKey] = {defaultKey}
end
for defaultKey, t in pairs(argKeys) do
local cfgValue = cfg[defaultKey]
local cfgValueType = type(cfgValue)
if cfgValueType == 'string' then
addKey(t, cfgValue, defaultKey)
elseif cfgValueType == 'table' then
for i, key in ipairs(cfgValue) do
addKey(t, key, defaultKey)
end
end
cfg[defaultKey] = nil -- Free the cfg value as we don't need it any more.
end
local function getParamMappings()
--[[
-- Returns a table of how parameter names map to namespace names. The keys
-- are the actual namespace names, in lower case, and the values are the
-- possible parameter names for that namespace, also in lower case. The
-- table entries are structured like this:
-- {
-- [''] = {'main'},
-- ['wikipedia'] = {'wikipedia', 'project', 'wp'},
-- ...
-- }
--]]
local mappings = {}
local mainNsName = mw.site.subjectNamespaces[0].name
mainNsName = mw.ustring.lower(mainNsName)
mappings[mainNsName] = mw.clone(argKeys.main)
mappings['talk'] = mw.clone(argKeys.talk)
for nsid, ns in pairs(mw.site.subjectNamespaces) do
if nsid ~= 0 then -- Exclude main namespace.
local nsname = mw.ustring.lower(ns.name)
local canonicalName = mw.ustring.lower(ns.canonicalName)
mappings[nsname] = {nsname}
if canonicalName ~= nsname then
table.insert(mappings[nsname], canonicalName)
end
for _, alias in ipairs(ns.aliases) do
table.insert(mappings[nsname], mw.ustring.lower(alias))
end
end
end
return mappings
end
return {
argKeys = argKeys,
cfg = cfg,
mappings = getParamMappings()
}
d224f42a258bc308ef3ad8cc8686cd7a4f47d005
Модуль:Namespace detect/config
828
77
127
126
2024-08-09T16:45:33Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Namespace detect configuration data --
-- --
-- This module stores configuration data for Module:Namespace detect. Here --
-- you can localise the module to your wiki's language. --
-- --
-- To activate a configuration item, you need to uncomment it. This means --
-- that you need to remove the text "-- " at the start of the line. --
--------------------------------------------------------------------------------
local cfg = {} -- Don't edit this line.
--------------------------------------------------------------------------------
-- Parameter names --
-- These configuration items specify custom parameter names. Values added --
-- here will work in addition to the default English parameter names. --
-- To add one extra name, you can use this format: --
-- --
-- cfg.foo = 'parameter name' --
-- --
-- To add multiple names, you can use this format: --
-- --
-- cfg.foo = {'parameter name 1', 'parameter name 2', 'parameter name 3'} --
--------------------------------------------------------------------------------
---- This parameter displays content for the main namespace:
-- cfg.main = 'main'
---- This parameter displays in talk namespaces:
-- cfg.talk = 'talk'
---- This parameter displays content for "other" namespaces (namespaces for which
---- parameters have not been specified):
-- cfg.other = 'other'
---- This parameter makes talk pages behave as though they are the corresponding
---- subject namespace. Note that this parameter is used with [[Module:Yesno]].
---- Edit that module to change the default values of "yes", "no", etc.
-- cfg.subjectns = 'subjectns'
---- This parameter sets a demonstration namespace:
-- cfg.demospace = 'demospace'
---- This parameter sets a specific page to compare:
cfg.demopage = 'page'
--------------------------------------------------------------------------------
-- Table configuration --
-- These configuration items allow customisation of the "table" function, --
-- used to generate a table of possible parameters in the module --
-- documentation. --
--------------------------------------------------------------------------------
---- The header for the namespace column in the wikitable containing the list of
---- possible subject-space parameters.
-- cfg.wikitableNamespaceHeader = 'Namespace'
---- The header for the wikitable containing the list of possible subject-space
---- parameters.
-- cfg.wikitableAliasesHeader = 'Aliases'
--------------------------------------------------------------------------------
-- End of configuration data --
--------------------------------------------------------------------------------
return cfg -- Don't edit this line.
0e4ff08d13c4b664d66b32c232deb129b77c1a56
Модуль:Citation/CS1
828
78
129
128
2024-08-09T16:53:51Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
require ('strict');
--[[--------------------------< F O R W A R D D E C L A R A T I O N S >--------------------------------------
each of these counts against the Lua upvalue limit
]]
local validation; -- functions in Module:Citation/CS1/Date_validation
local utilities; -- functions in Module:Citation/CS1/Utilities
local z = {}; -- table of tables in Module:Citation/CS1/Utilities
local identifiers; -- functions and tables in Module:Citation/CS1/Identifiers
local metadata; -- functions in Module:Citation/CS1/COinS
local cfg = {}; -- table of configuration tables that are defined in Module:Citation/CS1/Configuration
local whitelist = {}; -- table of tables listing valid template parameter names; defined in Module:Citation/CS1/Whitelist
local boxDate = require('Module:Calendar').bxDate; -- РУВИКИ: все даты делаем человекочитаемыми
--[[------------------< P A G E S C O P E V A R I A B L E S >---------------
declare variables here that have page-wide scope that are not brought in from
other modules; that are created here and used here
]]
local added_deprecated_cat; -- Boolean flag so that the category is added only once
local added_vanc_errs; -- Boolean flag so we only emit one Vancouver error / category
local added_generic_name_errs; -- Boolean flag so we only emit one generic name error / category and stop testing names once an error is encountered
local added_numeric_name_errs; -- Boolean flag so we only emit one numeric name error / category and stop testing names once an error is encountered
local added_numeric_name_maint; -- Boolean flag so we only emit one numeric name maint category and stop testing names once a category has been emitted
local Frame; -- holds the module's frame table
local is_preview_mode; -- true when article is in preview mode; false when using 'Preview page with this template' (previewing the module)
local is_sandbox; -- true when using sandbox modules to render citation
--[[--------------------------< F I R S T _ S E T >------------------------------------------------------------
Locates and returns the first set value in a table of values where the order established in the table,
left-to-right (or top-to-bottom), is the order in which the values are evaluated. Returns nil if none are set.
This version replaces the original 'for _, val in pairs do' and a similar version that used ipairs. With the pairs
version the order of evaluation could not be guaranteed. With the ipairs version, a nil value would terminate
the for-loop before it reached the actual end of the list.
]]
local function first_set (list, count)
local i = 1;
while i <= count do -- loop through all items in list
if utilities.is_set( list[i] ) then
return list[i]; -- return the first set list member
end
i = i + 1; -- point to next
end
end
--[[--------------------------< A D D _ V A N C _ E R R O R >----------------------------------------------------
Adds a single Vancouver system error message to the template's output regardless of how many error actually exist.
To prevent duplication, added_vanc_errs is nil until an error message is emitted.
added_vanc_errs is a Boolean declared in page scope variables above
]]
local function add_vanc_error (source, position)
if added_vanc_errs then return end
added_vanc_errs = true; -- note that we've added this category
utilities.set_message ('err_vancouver', {source, position});
end
--[[--------------------------< I S _ S C H E M E >------------------------------------------------------------
does this thing that purports to be a URI scheme seem to be a valid scheme? The scheme is checked to see if it
is in agreement with http://tools.ietf.org/html/std66#section-3.1 which says:
Scheme names consist of a sequence of characters beginning with a
letter and followed by any combination of letters, digits, plus
("+"), period ("."), or hyphen ("-").
returns true if it does, else false
]]
local function is_scheme (scheme)
return scheme and scheme:match ('^%a[%a%d%+%.%-]*:'); -- true if scheme is set and matches the pattern
end
--[=[-------------------------< I S _ D O M A I N _ N A M E >--------------------------------------------------
Does this thing that purports to be a domain name seem to be a valid domain name?
Syntax defined here: http://tools.ietf.org/html/rfc1034#section-3.5
BNF defined here: https://tools.ietf.org/html/rfc4234
Single character names are generally reserved; see https://tools.ietf.org/html/draft-ietf-dnsind-iana-dns-01#page-15;
see also [[Single-letter second-level domain]]
list of TLDs: https://www.iana.org/domains/root/db
RFC 952 (modified by RFC 1123) requires the first and last character of a hostname to be a letter or a digit. Between
the first and last characters the name may use letters, digits, and the hyphen.
Also allowed are IPv4 addresses. IPv6 not supported
domain is expected to be stripped of any path so that the last character in the last character of the TLD. tld
is two or more alpha characters. Any preceding '//' (from splitting a URL with a scheme) will be stripped
here. Perhaps not necessary but retained in case it is necessary for IPv4 dot decimal.
There are several tests:
the first character of the whole domain name including subdomains must be a letter or a digit
internationalized domain name (ASCII characters with .xn-- ASCII Compatible Encoding (ACE) prefix xn-- in the TLD) see https://tools.ietf.org/html/rfc3490
single-letter/digit second-level domains in the .org, .cash, and .today TLDs
q, x, and z SL domains in the .com TLD
i and q SL domains in the .net TLD
single-letter SL domains in the ccTLDs (where the ccTLD is two letters)
two-character SL domains in gTLDs (where the gTLD is two or more letters)
three-plus-character SL domains in gTLDs (where the gTLD is two or more letters)
IPv4 dot-decimal address format; TLD not allowed
returns true if domain appears to be a proper name and TLD or IPv4 address, else false
]=]
local function is_domain_name (domain)
if not domain then
return false; -- if not set, abandon
end
domain = domain:gsub ('^//', ''); -- strip '//' from domain name if present; done here so we only have to do it once
if not domain:match ('^[%w]') then -- first character must be letter or digit
return false;
end
if domain:match ('^%a+:') then -- hack to detect things that look like s:Page:Title where Page: is namespace at Wikisource
return false;
end
local patterns = { -- patterns that look like URLs
'%f[%w][%w][%w%-]+[%w]%.%a%a+$', -- three or more character hostname.hostname or hostname.tld
'%f[%w][%w][%w%-]+[%w]%.xn%-%-[%w]+$', -- internationalized domain name with ACE prefix
'%f[%a][qxz]%.com$', -- assigned one character .com hostname (x.com times out 2015-12-10)
'%f[%a][iq]%.net$', -- assigned one character .net hostname (q.net registered but not active 2015-12-10)
'%f[%w][%w]%.%a%a$', -- one character hostname and ccTLD (2 chars)
'%f[%w][%w][%w]%.%a%a+$', -- two character hostname and TLD
'^%d%d?%d?%.%d%d?%d?%.%d%d?%d?%.%d%d?%d?', -- IPv4 address
}
for _, pattern in ipairs (patterns) do -- loop through the patterns list
if domain:match (pattern) then
return true; -- if a match then we think that this thing that purports to be a URL is a URL
end
end
for _, d in ipairs (cfg.single_letter_2nd_lvl_domains_t) do -- look for single letter second level domain names for these top level domains
if domain:match ('%f[%w][%w]%.' .. d) then
return true
end
end
return false; -- no matches, we don't know what this thing is
end
--[[--------------------------< I S _ U R L >------------------------------------------------------------------
returns true if the scheme and domain parts of a URL appear to be a valid URL; else false.
This function is the last step in the validation process. This function is separate because there are cases that
are not covered by split_url(), for example is_parameter_ext_wikilink() which is looking for bracketted external
wikilinks.
]]
local function is_url (scheme, domain)
if utilities.is_set (scheme) then -- if scheme is set check it and domain
return is_scheme (scheme) and is_domain_name (domain);
else
return is_domain_name (domain); -- scheme not set when URL is protocol-relative
end
end
--[[--------------------------< S P L I T _ U R L >------------------------------------------------------------
Split a URL into a scheme, authority indicator, and domain.
First remove Fully Qualified Domain Name terminator (a dot following TLD) (if any) and any path(/), query(?) or fragment(#).
If protocol-relative URL, return nil scheme and domain else return nil for both scheme and domain.
When not protocol-relative, get scheme, authority indicator, and domain. If there is an authority indicator (one
or more '/' characters immediately following the scheme's colon), make sure that there are only 2.
Any URL that does not have news: scheme must have authority indicator (//). TODO: are there other common schemes
like news: that don't use authority indicator?
Strip off any port and path;
]]
local function split_url (url_str)
local scheme, authority, domain;
url_str = url_str:gsub ('([%a%d])%.?[/%?#].*$', '%1'); -- strip FQDN terminator and path(/), query(?), fragment (#) (the capture prevents false replacement of '//')
if url_str:match ('^//%S*') then -- if there is what appears to be a protocol-relative URL
domain = url_str:match ('^//(%S*)')
elseif url_str:match ('%S-:/*%S+') then -- if there is what appears to be a scheme, optional authority indicator, and domain name
scheme, authority, domain = url_str:match ('(%S-:)(/*)(%S+)'); -- extract the scheme, authority indicator, and domain portions
if utilities.is_set (authority) then
authority = authority:gsub ('//', '', 1); -- replace place 1 pair of '/' with nothing;
if utilities.is_set(authority) then -- if anything left (1 or 3+ '/' where authority should be) then
return scheme; -- return scheme only making domain nil which will cause an error message
end
else
if not scheme:match ('^news:') then -- except for news:..., MediaWiki won't link URLs that do not have authority indicator; TODO: a better way to do this test?
return scheme; -- return scheme only making domain nil which will cause an error message
end
end
domain = domain:gsub ('(%a):%d+', '%1'); -- strip port number if present
end
return scheme, domain;
end
--[[--------------------------< L I N K _ P A R A M _ O K >---------------------------------------------------
checks the content of |title-link=, |series-link=, |author-link=, etc. for properly formatted content: no wikilinks, no URLs
Link parameters are to hold the title of a Wikipedia article, so none of the WP:TITLESPECIALCHARACTERS are allowed:
# < > [ ] | { } _
except the underscore which is used as a space in wiki URLs and # which is used for section links
returns false when the value contains any of these characters.
When there are no illegal characters, this function returns TRUE if value DOES NOT appear to be a valid URL (the
|<param>-link= parameter is ok); else false when value appears to be a valid URL (the |<param>-link= parameter is NOT ok).
]]
local function link_param_ok (value)
local scheme, domain;
if value:find ('[<>%[%]|{}]') then -- if any prohibited characters
return false;
end
scheme, domain = split_url (value); -- get scheme or nil and domain or nil from URL;
return not is_url (scheme, domain); -- return true if value DOES NOT appear to be a valid URL
end
--[[--------------------------< L I N K _ T I T L E _ O K >---------------------------------------------------
Use link_param_ok() to validate |<param>-link= value and its matching |<title>= value.
|<title>= may be wiki-linked but not when |<param>-link= has a value. This function emits an error message when
that condition exists
check <link> for inter-language interwiki-link prefix. prefix must be a MediaWiki-recognized language
code and must begin with a colon.
]]
local function link_title_ok (link, lorig, title, torig)
local orig;
if utilities.is_set (link) then -- don't bother if <param>-link doesn't have a value
if not link_param_ok (link) then -- check |<param>-link= markup
orig = lorig; -- identify the failing link parameter
elseif title:find ('%[%[') then -- check |title= for wikilink markup
orig = torig; -- identify the failing |title= parameter
elseif link:match ('^%a+:') then -- if the link is what looks like an interwiki
local prefix = link:match ('^(%a+):'):lower(); -- get the interwiki prefix
if cfg.inter_wiki_map[prefix] then -- if prefix is in the map, must have preceding colon
orig = lorig; -- flag as error
end
end
end
if utilities.is_set (orig) then
link = ''; -- unset
utilities.set_message ('err_bad_paramlink', orig); -- URL or wikilink in |title= with |title-link=;
end
return link; -- link if ok, empty string else
end
--[[--------------------------< C H E C K _ U R L >------------------------------------------------------------
Determines whether a URL string appears to be valid.
First we test for space characters. If any are found, return false. Then split the URL into scheme and domain
portions, or for protocol-relative (//example.com) URLs, just the domain. Use is_url() to validate the two
portions of the URL. If both are valid, or for protocol-relative if domain is valid, return true, else false.
Because it is different from a standard URL, and because this module used external_link() to make external links
that work for standard and news: links, we validate newsgroup names here. The specification for a newsgroup name
is at https://tools.ietf.org/html/rfc5536#section-3.1.4
]]
local function check_url( url_str )
if nil == url_str:match ("^%S+$") then -- if there are any spaces in |url=value it can't be a proper URL
return false;
end
local scheme, domain;
scheme, domain = split_url (url_str); -- get scheme or nil and domain or nil from URL;
if 'news:' == scheme then -- special case for newsgroups
return domain:match('^[%a%d%+%-_]+%.[%a%d%+%-_%.]*[%a%d%+%-_]$');
end
return is_url (scheme, domain); -- return true if value appears to be a valid URL
end
--[=[-------------------------< I S _ P A R A M E T E R _ E X T _ W I K I L I N K >----------------------------
Return true if a parameter value has a string that begins and ends with square brackets [ and ] and the first
non-space characters following the opening bracket appear to be a URL. The test will also find external wikilinks
that use protocol-relative URLs. Also finds bare URLs.
The frontier pattern prevents a match on interwiki-links which are similar to scheme:path URLs. The tests that
find bracketed URLs are required because the parameters that call this test (currently |title=, |chapter=, |work=,
and |publisher=) may have wikilinks and there are articles or redirects like '//Hus' so, while uncommon, |title=[[//Hus]]
is possible as might be [[en://Hus]].
]=]
local function is_parameter_ext_wikilink (value)
local scheme, domain;
if value:match ('%f[%[]%[%a%S*:%S+.*%]') then -- if ext. wikilink with scheme and domain: [xxxx://yyyyy.zzz]
scheme, domain = split_url (value:match ('%f[%[]%[(%a%S*:%S+).*%]'));
elseif value:match ('%f[%[]%[//%S+.*%]') then -- if protocol-relative ext. wikilink: [//yyyyy.zzz]
scheme, domain = split_url (value:match ('%f[%[]%[(//%S+).*%]'));
elseif value:match ('%a%S*:%S+') then -- if bare URL with scheme; may have leading or trailing plain text
scheme, domain = split_url (value:match ('(%a%S*:%S+)'));
elseif value:match ('//%S+') then -- if protocol-relative bare URL: //yyyyy.zzz; may have leading or trailing plain text
scheme, domain = split_url (value:match ('(//%S+)')); -- what is left should be the domain
else
return false; -- didn't find anything that is obviously a URL
end
return is_url (scheme, domain); -- return true if value appears to be a valid URL
end
--[[-------------------------< C H E C K _ F O R _ U R L >-----------------------------------------------------
loop through a list of parameters and their values. Look at the value and if it has an external link, emit an error message.
]]
local function check_for_url (parameter_list, error_list)
for k, v in pairs (parameter_list) do -- for each parameter in the list
if is_parameter_ext_wikilink (v) then -- look at the value; if there is a URL add an error message
table.insert (error_list, utilities.wrap_style ('parameter', k));
end
end
end
--[[--------------------------< S A F E _ F O R _ U R L >------------------------------------------------------
Escape sequences for content that will be used for URL descriptions
]]
local function safe_for_url( str )
if str:match( "%[%[.-%]%]" ) ~= nil then
utilities.set_message ('err_wikilink_in_url', {});
end
return str:gsub( '[%[%]\n]', {
['['] = '[',
[']'] = ']',
['\n'] = ' ' } );
end
--[[--------------------------< E X T E R N A L _ L I N K >----------------------------------------------------
Format an external link with error checking
]]
local function external_link (URL, label, source, access)
local err_msg = '';
local domain;
local path;
local base_url;
if not utilities.is_set (label) then
label = URL;
if utilities.is_set (source) then
utilities.set_message ('err_bare_url_missing_title', {utilities.wrap_style ('parameter', source)});
else
error (cfg.messages["bare_url_no_origin"]); -- programmer error; valid parameter name does not have matching meta-parameter
end
end
if not check_url (URL) then
utilities.set_message ('err_bad_url', {utilities.wrap_style ('parameter', source)});
end
domain, path = URL:match ('^([/%.%-%+:%a%d]+)([/%?#].*)$'); -- split the URL into scheme plus domain and path
if path then -- if there is a path portion
path = path:gsub ('[%[%]]', {['['] = '%5b', [']'] = '%5d'}); -- replace '[' and ']' with their percent-encoded values
URL = table.concat ({domain, path}); -- and reassemble
end
base_url = table.concat ({ "[", URL, " ", safe_for_url (label), "]" }); -- assemble a wiki-markup URL
if utilities.is_set (access) then -- access level (subscription, registration, limited)
base_url = utilities.substitute (cfg.presentation['ext-link-access-signal'], {cfg.presentation[access].class, cfg.presentation[access].title, base_url}); -- add the appropriate icon
end
return base_url;
end
--[[--------------------------< F O R M A T E _ D A T E >-----------------------------------------------------
Call a calendar module that turns all non-local language dates (including ISO dates) into local language dates.
Used for archiving and review dates.
]]
local function formatDate(txtDateIn, strFormat, params)
local txtDateOut, date, status = boxDate(txtDateIn, strFormat, params)
if status.brk then
return error(status.errorText)
else
return txtDateOut
end
end
--[[--------------------------< D E P R E C A T E D _ P A R A M E T E R >--------------------------------------
Categorize and emit an error message when the citation contains one or more deprecated parameters. The function includes the
offending parameter name to the error message. Only one error message is emitted regardless of the number of deprecated
parameters in the citation.
added_deprecated_cat is a Boolean declared in page scope variables above
]]
local function deprecated_parameter(name)
if not added_deprecated_cat then
added_deprecated_cat = true; -- note that we've added this category
utilities.set_message ('err_deprecated_params', {name}); -- add error message
end
end
--[=[-------------------------< K E R N _ Q U O T E S >--------------------------------------------------------
Apply kerning to open the space between the quote mark provided by the module and a leading or trailing quote
mark contained in a |title= or |chapter= parameter's value.
This function will positive kern either single or double quotes:
"'Unkerned title with leading and trailing single quote marks'"
" 'Kerned title with leading and trailing single quote marks' " (in real life the kerning isn't as wide as this example)
Double single quotes (italic or bold wiki-markup) are not kerned.
Replaces Unicode quote marks in plain text or in the label portion of a [[L|D]] style wikilink with typewriter
quote marks regardless of the need for kerning. Unicode quote marks are not replaced in simple [[D]] wikilinks.
Call this function for chapter titles, for website titles, etc.; not for book titles.
]=]
local function kern_quotes (str)
local cap = '';
local wl_type, label, link;
wl_type, label, link = utilities.is_wikilink (str); -- wl_type is: 0, no wl (text in label variable); 1, [[D]]; 2, [[L|D]]
if 1 == wl_type then -- [[D]] simple wikilink with or without quote marks
if mw.ustring.match (str, '%[%[[\"“”\'‘’].+[\"“”\'‘’]%]%]') then -- leading and trailing quote marks
str = utilities.substitute (cfg.presentation['kern-left'], str);
str = utilities.substitute (cfg.presentation['kern-right'], str);
elseif mw.ustring.match (str, '%[%[[\"“”\'‘’].+%]%]') then -- leading quote marks
str = utilities.substitute (cfg.presentation['kern-left'], str);
elseif mw.ustring.match (str, '%[%[.+[\"“”\'‘’]%]%]') then -- trailing quote marks
str = utilities.substitute (cfg.presentation['kern-right'], str);
end
else -- plain text or [[L|D]]; text in label variable
label = mw.ustring.gsub (label, '[“”]', '\"'); -- replace “” (U+201C & U+201D) with " (typewriter double quote mark)
label = mw.ustring.gsub (label, '[‘’]', '\''); -- replace ‘’ (U+2018 & U+2019) with ' (typewriter single quote mark)
cap = mw.ustring.match (label, "^([\"\'][^\'].+)"); -- match leading double or single quote but not doubled single quotes (italic markup)
if utilities.is_set (cap) then
label = utilities.substitute (cfg.presentation['kern-left'], cap);
end
cap = mw.ustring.match (label, "^(.+[^\'][\"\'])$") -- match trailing double or single quote but not doubled single quotes (italic markup)
if utilities.is_set (cap) then
label = utilities.substitute (cfg.presentation['kern-right'], cap);
end
if 2 == wl_type then
str = utilities.make_wikilink (link, label); -- reassemble the wikilink
else
str = label;
end
end
return str;
end
--[[--------------------------< F O R M A T _ S C R I P T _ V A L U E >----------------------------------------
|script-title= holds title parameters that are not written in Latin-based scripts: Chinese, Japanese, Arabic, Hebrew, etc. These scripts should
not be italicized and may be written right-to-left. The value supplied by |script-title= is concatenated onto Title after Title has been wrapped
in italic markup.
Regardless of language, all values provided by |script-title= are wrapped in <bdi>...</bdi> tags to isolate RTL languages from the English left to right.
|script-title= provides a unique feature. The value in |script-title= may be prefixed with a two-character ISO 639-1 language code and a colon:
|script-title=ja:*** *** (where * represents a Japanese character)
Spaces between the two-character code and the colon and the colon and the first script character are allowed:
|script-title=ja : *** ***
|script-title=ja: *** ***
|script-title=ja :*** ***
Spaces preceding the prefix are allowed: |script-title = ja:*** ***
The prefix is checked for validity. If it is a valid ISO 639-1 language code, the lang attribute (lang="ja") is added to the <bdi> tag so that browsers can
know the language the tag contains. This may help the browser render the script more correctly. If the prefix is invalid, the lang attribute
is not added. At this time there is no error message for this condition.
Supports |script-title=, |script-chapter=, |script-<periodical>=
]]
local function format_script_value (script_value, script_param)
local lang=''; -- initialize to empty string
local name;
if script_value:match('^%l%l%l?%s*:') then -- if first 3 or 4 non-space characters are script language prefix
lang = script_value:match('^(%l%l%l?)%s*:%s*%S.*'); -- get the language prefix or nil if there is no script
if not utilities.is_set (lang) then
utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['missing title part']}); -- prefix without 'title'; add error message
return ''; -- script_value was just the prefix so return empty string
end
-- if we get this far we have prefix and script
name = cfg.lang_tag_remap[lang] or mw.language.fetchLanguageName( lang, cfg.this_wiki_code ); -- get language name so that we can use it to categorize
if utilities.is_set (name) then -- is prefix a proper ISO 639-1 language code?
script_value = script_value:gsub ('^%l+%s*:%s*', ''); -- strip prefix from script
-- is prefix one of these language codes?
if utilities.in_array (lang, cfg.script_lang_codes) then
utilities.add_prop_cat ('script', {name, lang})
else
utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['unknown language code']}); -- unknown script-language; add error message
end
lang = ' lang="' .. lang .. '" '; -- convert prefix into a lang attribute
else
utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['invalid language code']}); -- invalid language code; add error message
lang = ''; -- invalid so set lang to empty string
end
else
utilities.set_message ('err_script_parameter', {script_param, cfg.err_msg_supl['missing prefix']}); -- no language code prefix; add error message
end
script_value = utilities.substitute (cfg.presentation['bdi'], {lang, script_value}); -- isolate in case script is RTL
return script_value;
end
--[[--------------------------< S C R I P T _ C O N C A T E N A T E >------------------------------------------
Initially for |title= and |script-title=, this function concatenates those two parameter values after the script
value has been wrapped in <bdi> tags.
]]
local function script_concatenate (title, script, script_param)
if utilities.is_set (script) then
script = format_script_value (script, script_param); -- <bdi> tags, lang attribute, categorization, etc.; returns empty string on error
if utilities.is_set (script) then
title = title .. ' ' .. script; -- concatenate title and script title
end
end
return title;
end
--[[--------------------------< W R A P _ M S G >--------------------------------------------------------------
Applies additional message text to various parameter values. Supplied string is wrapped using a message_list
configuration taking one argument. Supports lower case text for {{citation}} templates. Additional text taken
from citation_config.messages - the reason this function is similar to but separate from wrap_style().
]]
local function wrap_msg (key, str, lower)
if not utilities.is_set ( str ) then
return "";
end
if true == lower then
local msg;
msg = cfg.messages[key]:lower(); -- set the message to lower case before
return utilities.substitute ( msg, str ); -- including template text
else
return utilities.substitute ( cfg.messages[key], str );
end
end
--[[----------------< W I K I S O U R C E _ U R L _ M A K E >-------------------
Makes a Wikisource URL from Wikisource interwiki-link. Returns the URL and appropriate
label; nil else.
str is the value assigned to |chapter= (or aliases) or |title= or |title-link=
]]
local function wikisource_url_make (str)
local wl_type, D, L;
local ws_url, ws_label;
local wikisource_prefix = table.concat ({'https://', cfg.this_wiki_code, '.wikisource.org/wiki/'});
wl_type, D, L = utilities.is_wikilink (str); -- wl_type is 0 (not a wikilink), 1 (simple wikilink), 2 (complex wikilink)
if 0 == wl_type then -- not a wikilink; might be from |title-link=
str = D:match ('^[Ww]ikisource:(.+)') or D:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace
if utilities.is_set (str) then
ws_url = table.concat ({ -- build a Wikisource URL
wikisource_prefix, -- prefix
str, -- article title
});
ws_label = str; -- label for the URL
end
elseif 1 == wl_type then -- simple wikilink: [[Wikisource:ws article]]
str = D:match ('^[Ww]ikisource:(.+)') or D:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace
if utilities.is_set (str) then
ws_url = table.concat ({ -- build a Wikisource URL
wikisource_prefix, -- prefix
str, -- article title
});
ws_label = str; -- label for the URL
end
elseif 2 == wl_type then -- non-so-simple wikilink: [[Wikisource:ws article|displayed text]] ([[L|D]])
str = L:match ('^[Ww]ikisource:(.+)') or L:match ('^[Ss]:(.+)'); -- article title from interwiki link with long-form or short-form namespace
if utilities.is_set (str) then
ws_label = D; -- get ws article name from display portion of interwiki link
ws_url = table.concat ({ -- build a Wikisource URL
wikisource_prefix, -- prefix
str, -- article title without namespace from link portion of wikilink
});
end
end
if ws_url then
ws_url = mw.uri.encode (ws_url, 'WIKI'); -- make a usable URL
ws_url = ws_url:gsub ('%%23', '#'); -- undo percent-encoding of fragment marker
end
return ws_url, ws_label, L or D; -- return proper URL or nil and a label or nil
end
--[[----------------< F O R M A T _ P E R I O D I C A L >-----------------------
Format the three periodical parameters: |script-<periodical>=, |<periodical>=,
and |trans-<periodical>= into a single Periodical meta-parameter.
]]
local function format_periodical (script_periodical, script_periodical_source, periodical, trans_periodical)
if not utilities.is_set (periodical) then
periodical = ''; -- to be safe for concatenation
else
periodical = utilities.wrap_style ('italic-title', periodical); -- style
end
periodical = script_concatenate (periodical, script_periodical, script_periodical_source); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
if utilities.is_set (trans_periodical) then
trans_periodical = utilities.wrap_style ('trans-italic-title', trans_periodical);
if utilities.is_set (periodical) then
periodical = periodical .. ' ' .. trans_periodical;
else -- here when trans-periodical without periodical or script-periodical
periodical = trans_periodical;
utilities.set_message ('err_trans_missing_title', {'periodical'});
end
end
return periodical;
end
--[[------------------< F O R M A T _ C H A P T E R _ T I T L E >---------------
Format the four chapter parameters: |script-chapter=, |chapter=, |trans-chapter=,
and |chapter-url= into a single chapter meta- parameter (chapter_url_source used
for error messages).
]]
local function format_chapter_title (script_chapter, script_chapter_source, chapter, chapter_source, trans_chapter, trans_chapter_source, chapter_url, chapter_url_source, no_quotes, access)
local ws_url, ws_label, L = wikisource_url_make (chapter); -- make a wikisource URL and label from a wikisource interwiki link
if ws_url then
ws_label = ws_label:gsub ('_', ' '); -- replace underscore separators with space characters
chapter = ws_label;
end
if not utilities.is_set (chapter) then
chapter = ''; -- to be safe for concatenation
else
if false == no_quotes then
chapter = kern_quotes (chapter); -- if necessary, separate chapter title's leading and trailing quote marks from module provided quote marks
chapter = utilities.wrap_style ('quoted-title', chapter);
end
end
chapter = script_concatenate (chapter, script_chapter, script_chapter_source); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
if utilities.is_set (chapter_url) then
chapter = external_link (chapter_url, chapter, chapter_url_source, access); -- adds bare_url_missing_title error if appropriate
elseif ws_url then
chapter = external_link (ws_url, chapter .. ' ', 'ws link in chapter'); -- adds bare_url_missing_title error if appropriate; space char to move icon away from chap text; TODO: better way to do this?
chapter = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, chapter});
end
if utilities.is_set (trans_chapter) then
trans_chapter = utilities.wrap_style ('trans-quoted-title', trans_chapter);
if utilities.is_set (chapter) then
chapter = chapter .. ' ' .. trans_chapter;
else -- here when trans_chapter without chapter or script-chapter
chapter = trans_chapter;
chapter_source = trans_chapter_source:match ('trans%-?(.+)'); -- when no chapter, get matching name from trans-<param>
utilities.set_message ('err_trans_missing_title', {chapter_source});
end
end
return chapter;
end
--[[----------------< H A S _ I N V I S I B L E _ C H A R S >-------------------
This function searches a parameter's value for non-printable or invisible characters.
The search stops at the first match.
This function will detect the visible replacement character when it is part of the Wikisource.
Detects but ignores nowiki and math stripmarkers. Also detects other named stripmarkers
(gallery, math, pre, ref) and identifies them with a slightly different error message.
See also coins_cleanup().
Output of this function is an error message that identifies the character or the
Unicode group, or the stripmarker that was detected along with its position (or,
for multi-byte characters, the position of its first byte) in the parameter value.
]]
local function has_invisible_chars (param, v)
local position = ''; -- position of invisible char or starting position of stripmarker
local capture; -- used by stripmarker detection to hold name of the stripmarker
local stripmarker; -- boolean set true when a stripmarker is found
capture = string.match (v, '[%w%p ]*'); -- test for values that are simple ASCII text and bypass other tests if true
if capture == v then -- if same there are no Unicode characters
return;
end
for _, invisible_char in ipairs (cfg.invisible_chars) do
local char_name = invisible_char[1]; -- the character or group name
local pattern = invisible_char[2]; -- the pattern used to find it
position, _, capture = mw.ustring.find (v, pattern); -- see if the parameter value contains characters that match the pattern
if position and (cfg.invisible_defs.zwj == capture) then -- if we found a zero-width joiner character
if mw.ustring.find (v, cfg.indic_script) then -- it's ok if one of the Indic scripts
position = nil; -- unset position
elseif cfg.emoji_t[mw.ustring.codepoint (v, position+1)] then -- is zwj followed by a character listed in emoji{}?
position = nil; -- unset position
end
end
if position then
if 'nowiki' == capture or 'math' == capture or -- nowiki and math stripmarkers (not an error condition)
('templatestyles' == capture and utilities.in_array (param, {'id', 'quote'})) then -- templatestyles stripmarker allowed in these parameters
stripmarker = true; -- set a flag
elseif true == stripmarker and cfg.invisible_defs.del == capture then -- because stripmakers begin and end with the delete char, assume that we've found one end of a stripmarker
position = nil; -- unset
else
local err_msg;
if capture and not (cfg.invisible_defs.del == capture or cfg.invisible_defs.zwj == capture) then
err_msg = capture .. ' ' .. char_name;
else
err_msg = char_name .. ' ' .. 'character';
end
utilities.set_message ('err_invisible_char', {err_msg, utilities.wrap_style ('parameter', param), position}); -- add error message
return; -- and done with this parameter
end
end
end
end
--[[-------------------< A R G U M E N T _ W R A P P E R >----------------------
Argument wrapper. This function provides support for argument mapping defined
in the configuration file so that multiple names can be transparently aliased to
single internal variable.
]]
local function argument_wrapper ( args )
local origin = {};
return setmetatable({
ORIGIN = function ( self, k )
local dummy = self[k]; -- force the variable to be loaded.
return origin[k];
end
},
{
__index = function ( tbl, k )
if origin[k] ~= nil then
return nil;
end
local args, list, v = args, cfg.aliases[k];
if type( list ) == 'table' then
v, origin[k] = utilities.select_one ( args, list, 'err_redundant_parameters' );
if origin[k] == nil then
origin[k] = ''; -- Empty string, not nil
end
elseif list ~= nil then
v, origin[k] = args[list], list;
else
-- maybe let through instead of raising an error?
-- v, origin[k] = args[k], k;
error( cfg.messages['unknown_argument_map'] .. ': ' .. k);
end
-- Empty strings, not nil;
if v == nil then
v = '';
origin[k] = '';
end
tbl = rawset( tbl, k, v );
return v;
end,
});
end
--[[--------------------------< N O W R A P _ D A T E >-------------------------
When date is YYYY-MM-DD format wrap in nowrap span: <span ...>YYYY-MM-DD</span>.
When date is DD MMMM YYYY or is MMMM DD, YYYY then wrap in nowrap span:
<span ...>DD MMMM</span> YYYY or <span ...>MMMM DD,</span> YYYY
DOES NOT yet support MMMM YYYY or any of the date ranges.
]]
local function nowrap_date (date)
local cap = '';
local cap2 = '';
if date:match("^%d%d%d%d%-%d%d%-%d%d$") then
date = utilities.substitute (cfg.presentation['nowrap1'], date);
elseif date:match("^%a+%s*%d%d?,%s+%d%d%d%d$") or date:match ("^%d%d?%s*%a+%s+%d%d%d%d$") then
cap, cap2 = string.match (date, "^(.*)%s+(%d%d%d%d)$");
date = utilities.substitute (cfg.presentation['nowrap2'], {cap, cap2});
end
return date;
end
--[[--------------------------< S E T _ T I T L E T Y P E >---------------------
This function sets default title types (equivalent to the citation including
|type=<default value>) for those templates that have defaults. Also handles the
special case where it is desirable to omit the title type from the rendered citation
(|type=none).
]]
local function set_titletype (cite_class, title_type)
if utilities.is_set (title_type) then
if 'none' == cfg.keywords_xlate[title_type] then
title_type = ''; -- if |type=none then type parameter not displayed
end
return title_type; -- if |type= has been set to any other value use that value
end
return cfg.title_types [cite_class] or ''; -- set template's default title type; else empty string for concatenation
end
--[[--------------------------< S A F E _ J O I N >-----------------------------
Joins a sequence of strings together while checking for duplicate separation characters.
]]
local function safe_join( tbl, duplicate_char )
local f = {}; -- create a function table appropriate to type of 'duplicate character'
if 1 == #duplicate_char then -- for single byte ASCII characters use the string library functions
f.gsub = string.gsub
f.match = string.match
f.sub = string.sub
else -- for multi-byte characters use the ustring library functions
f.gsub = mw.ustring.gsub
f.match = mw.ustring.match
f.sub = mw.ustring.sub
end
local str = ''; -- the output string
local comp = ''; -- what does 'comp' mean?
local end_chr = '';
local trim;
for _, value in ipairs( tbl ) do
if value == nil then value = ''; end
if str == '' then -- if output string is empty
str = value; -- assign value to it (first time through the loop)
elseif value ~= '' then
if value:sub(1, 1) == '<' then -- special case of values enclosed in spans and other markup.
comp = value:gsub( "%b<>", "" ); -- remove HTML markup (<span>string</span> -> string)
else
comp = value;
end
-- typically duplicate_char is sepc
if f.sub(comp, 1, 1) == duplicate_char then -- is first character same as duplicate_char? why test first character?
-- Because individual string segments often (always?) begin with terminal punct for the
-- preceding segment: 'First element' .. 'sepc next element' .. etc.?
trim = false;
end_chr = f.sub(str, -1, -1); -- get the last character of the output string
-- str = str .. "<HERE(enchr=" .. end_chr .. ")" -- debug stuff?
if end_chr == duplicate_char then -- if same as separator
str = f.sub(str, 1, -2); -- remove it
elseif end_chr == "'" then -- if it might be wiki-markup
if f.sub(str, -3, -1) == duplicate_char .. "''" then -- if last three chars of str are sepc''
str = f.sub(str, 1, -4) .. "''"; -- remove them and add back ''
elseif f.sub(str, -5, -1) == duplicate_char .. "]]''" then -- if last five chars of str are sepc]]''
trim = true; -- why? why do this and next differently from previous?
elseif f.sub(str, -4, -1) == duplicate_char .. "]''" then -- if last four chars of str are sepc]''
trim = true; -- same question
end
elseif end_chr == "]" then -- if it might be wiki-markup
if f.sub(str, -3, -1) == duplicate_char .. "]]" then -- if last three chars of str are sepc]] wikilink
trim = true;
elseif f.sub(str, -3, -1) == duplicate_char .. '"]' then -- if last three chars of str are sepc"] quoted external link
trim = true;
elseif f.sub(str, -2, -1) == duplicate_char .. "]" then -- if last two chars of str are sepc] external link
trim = true;
elseif f.sub(str, -4, -1) == duplicate_char .. "'']" then -- normal case when |url=something & |title=Title.
trim = true;
end
elseif end_chr == " " then -- if last char of output string is a space
if f.sub(str, -2, -1) == duplicate_char .. " " then -- if last two chars of str are <sepc><space>
str = f.sub(str, 1, -3); -- remove them both
end
end
if trim then
if value ~= comp then -- value does not equal comp when value contains HTML markup
local dup2 = duplicate_char;
if f.match(dup2, "%A" ) then dup2 = "%" .. dup2; end -- if duplicate_char not a letter then escape it
value = f.gsub(value, "(%b<>)" .. dup2, "%1", 1 ) -- remove duplicate_char if it follows HTML markup
else
value = f.sub(value, 2, -1 ); -- remove duplicate_char when it is first character
end
end
end
str = str .. value; -- add it to the output string
end
end
return str;
end
--[[--------------------------< I S _ S U F F I X >-----------------------------
returns true if suffix is properly formed Jr, Sr, or ordinal in the range 1–9.
Puncutation not allowed.
]]
local function is_suffix (suffix)
if utilities.in_array (suffix, {'Jr', 'Sr', 'Jnr', 'Snr', '1st', '2nd', '3rd'}) or suffix:match ('^%dth$') then
return true;
end
return false;
end
--[[--------------------< I S _ G O O D _ V A N C _ N A M E >-------------------
For Vancouver style, author/editor names are supposed to be rendered in Latin
(read ASCII) characters. When a name uses characters that contain diacritical
marks, those characters are to be converted to the corresponding Latin
character. When a name is written using a non-Latin alphabet or logogram, that
name is to be transliterated into Latin characters. The module doesn't do this
so editors may/must.
This test allows |first= and |last= names to contain any of the letters defined
in the four Unicode Latin character sets
[http://www.unicode.org/charts/PDF/U0000.pdf C0 Controls and Basic Latin] 0041–005A, 0061–007A
[http://www.unicode.org/charts/PDF/U0080.pdf C1 Controls and Latin-1 Supplement] 00C0–00D6, 00D8–00F6, 00F8–00FF
[http://www.unicode.org/charts/PDF/U0100.pdf Latin Extended-A] 0100–017F
[http://www.unicode.org/charts/PDF/U0180.pdf Latin Extended-B] 0180–01BF, 01C4–024F
|lastn= also allowed to contain hyphens, spaces, and apostrophes.
(http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35029/)
|firstn= also allowed to contain hyphens, spaces, apostrophes, and periods
This original test:
if nil == mw.ustring.find (last, "^[A-Za-zÀ-ÖØ-öø-ƿDŽ-ɏ%-%s%']*$")
or nil == mw.ustring.find (first, "^[A-Za-zÀ-ÖØ-öø-ƿDŽ-ɏ%-%s%'%.]+[2-6%a]*$") then
was written outside of the code editor and pasted here because the code editor
gets confused between character insertion point and cursor position. The test has
been rewritten to use decimal character escape sequence for the individual bytes
of the Unicode characters so that it is not necessary to use an external editor
to maintain this code.
\195\128-\195\150 – À-Ö (U+00C0–U+00D6 – C0 controls)
\195\152-\195\182 – Ø-ö (U+00D8-U+00F6 – C0 controls)
\195\184-\198\191 – ø-ƿ (U+00F8-U+01BF – C0 controls, Latin extended A & B)
\199\132-\201\143 – DŽ-ɏ (U+01C4-U+024F – Latin extended B)
]]
local function is_good_vanc_name (last, first, suffix, position)
if not suffix then
if first:find ('[,%s]') then -- when there is a space or comma, might be first name/initials + generational suffix
first = first:match ('(.-)[,%s]+'); -- get name/initials
suffix = first:match ('[,%s]+(.+)$'); -- get generational suffix
end
end
if utilities.is_set (suffix) then
if not is_suffix (suffix) then
add_vanc_error (cfg.err_msg_supl.suffix, position);
return false; -- not a name with an appropriate suffix
end
end
if nil == mw.ustring.find (last, "^[A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143\225\184\128-\225\187\191%-%s%']*$") or
nil == mw.ustring.find (first, "^[A-Za-z\195\128-\195\150\195\152-\195\182\195\184-\198\191\199\132-\201\143\225\184\128-\225\187\191%-%s%'%.]*$") then
add_vanc_error (cfg.err_msg_supl['non-Latin char'], position);
return false; -- not a string of Latin characters; Vancouver requires Romanization
end;
return true;
end
--[[--------------------------< R E D U C E _ T O _ I N I T I A L S >------------------------------------------
Attempts to convert names to initials in support of |name-list-style=vanc.
Names in |firstn= may be separated by spaces or hyphens, or for initials, a period.
See http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35062/.
Vancouver style requires family rank designations (Jr, II, III, etc.) to be rendered
as Jr, 2nd, 3rd, etc. See http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35085/.
This code only accepts and understands generational suffix in the Vancouver format
because Roman numerals look like, and can be mistaken for, initials.
This function uses ustring functions because firstname initials may be any of the
Unicode Latin characters accepted by is_good_vanc_name ().
]]
local function reduce_to_initials (first, position)
if first:find (',', 1, true) then
return first; -- commas not allowed; abandon
end
local name, suffix = mw.ustring.match (first, "^(%u+) ([%dJS][%drndth]+)$");
if not name then -- if not initials and a suffix
name = mw.ustring.match (first, "^(%u+)$"); -- is it just initials?
end
if name then -- if first is initials with or without suffix
if 3 > mw.ustring.len (name) then -- if one or two initials
if suffix then -- if there is a suffix
if is_suffix (suffix) then -- is it legitimate?
return first; -- one or two initials and a valid suffix so nothing to do
else
add_vanc_error (cfg.err_msg_supl.suffix, position); -- one or two initials with invalid suffix so error message
return first; -- and return first unmolested
end
else
return first; -- one or two initials without suffix; nothing to do
end
end
end -- if here then name has 3 or more uppercase letters so treat them as a word
local initials_t, names_t = {}, {}; -- tables to hold name parts and initials
local i = 1; -- counter for number of initials
names_t = mw.text.split (first, '[%s%-]+'); -- split into a sequence of names and possible suffix
while names_t[i] do -- loop through the sequence
if 1 < i and names_t[i]:match ('[%dJS][%drndth]+%.?$') then -- if not the first name, and looks like a suffix (may have trailing dot)
names_t[i] = names_t[i]:gsub ('%.', ''); -- remove terminal dot if present
if is_suffix (names_t[i]) then -- if a legitimate suffix
table.insert (initials_t, ' ' .. names_t[i]); -- add a separator space, insert at end of initials sequence
break; -- and done because suffix must fall at the end of a name
end -- no error message if not a suffix; possibly because of Romanization
end
if 3 > i then
table.insert (initials_t, mw.ustring.sub (names_t[i], 1, 1)); -- insert the initial at end of initials sequence
end
i = i + 1; -- bump the counter
end
return table.concat (initials_t); -- Vancouver format does not include spaces.
end
--[[--------------------------< I N T E R W I K I _ P R E F I X E N _ G E T >----------------------------------
extract interwiki prefixen from <value>. Returns two one or two values:
false – no prefixen
nil – prefix exists but not recognized
project prefix, language prefix – when value has either of:
:<project>:<language>:<article>
:<language>:<project>:<article>
project prefix, nil – when <value> has only a known single-letter prefix
nil, language prefix – when <value> has only a known language prefix
accepts single-letter project prefixen: 'd' (wikidata), 's' (wikisource), and 'w' (wikipedia) prefixes; at this
writing, the other single-letter prefixen (b (wikibook), c (commons), m (meta), n (wikinews), q (wikiquote), and
v (wikiversity)) are not supported.
]]
local function interwiki_prefixen_get (value, is_link)
if not value:find (':%l+:') then -- if no prefix
return false; -- abandon; boolean here to distinguish from nil fail returns later
end
local prefix_patterns_linked_t = { -- sequence of valid interwiki and inter project prefixen
'^%[%[:([dsw]):(%l%l+):', -- wikilinked; project and language prefixes
'^%[%[:(%l%l+):([dsw]):', -- wikilinked; language and project prefixes
'^%[%[:([dsw]):', -- wikilinked; project prefix
'^%[%[:(%l%l+):', -- wikilinked; language prefix
}
local prefix_patterns_unlinked_t = { -- sequence of valid interwiki and inter project prefixen
'^:([dsw]):(%l%l+):', -- project and language prefixes
'^:(%l%l+):([dsw]):', -- language and project prefixes
'^:([dsw]):', -- project prefix
'^:(%l%l+):', -- language prefix
}
local cap1, cap2;
for _, pattern in ipairs ((is_link and prefix_patterns_linked_t) or prefix_patterns_unlinked_t) do
cap1, cap2 = value:match (pattern);
if cap1 then
break; -- found a match so stop looking
end
end
if cap1 and cap2 then -- when both then :project:language: or :language:project: (both forms allowed)
if 1 == #cap1 then -- length == 1 then :project:language:
if cfg.inter_wiki_map[cap2] then -- is language prefix in the interwiki map?
return cap1, cap2; -- return interwiki project and interwiki language
end
else -- here when :language:project:
if cfg.inter_wiki_map[cap1] then -- is language prefix in the interwiki map?
return cap2, cap1; -- return interwiki project and interwiki language
end
end
return nil; -- unknown interwiki language
elseif not (cap1 or cap2) then -- both are nil?
return nil; -- we got something that looks like a project prefix but isn't; return fail
elseif 1 == #cap1 then -- here when one capture
return cap1, nil; -- length is 1 so return project, nil language
else -- here when one capture and its length it more than 1
if cfg.inter_wiki_map[cap1] then -- is language prefix in the interwiki map?
return nil, cap1; -- return nil project, language
end
end
end
--[[--------------------------< L I S T _ P E O P L E >--------------------------
Formats a list of people (authors, contributors, editors, interviewers, translators)
names in the list will be linked when
|<name>-link= has a value
|<name>-mask- does NOT have a value; masked names are presumed to have been
rendered previously so should have been linked there
when |<name>-mask=0, the associated name is not rendered
]]
local function list_people (control, people, etal)
local sep;
local namesep;
local format = control.format;
local maximum = control.maximum;
local name_list = {};
if 'vanc' == format then -- Vancouver-like name styling?
sep = cfg.presentation['sep_nl_vanc']; -- name-list separator between names is a comma
namesep = cfg.presentation['sep_name_vanc']; -- last/first separator is a space
else
sep = cfg.presentation['sep_nl']; -- name-list separator between names is a semicolon
namesep = cfg.presentation['sep_name']; -- last/first separator is <comma><space>
end
if sep:sub (-1, -1) ~= " " then sep = sep .. " " end
if utilities.is_set (maximum) and maximum < 1 then return "", 0; end -- returned 0 is for EditorCount; not used for other names
for i, person in ipairs (people) do
if utilities.is_set (person.last) then
local mask = person.mask;
local one;
local sep_one = sep;
if utilities.is_set (maximum) and i > maximum then
etal = true;
break;
end
if mask then
local n = tonumber (mask); -- convert to a number if it can be converted; nil else
if n then
one = 0 ~= n and string.rep("—", n) or nil; -- make a string of (n > 0) mdashes, nil else, to replace name
person.link = nil; -- don't create link to name if name is replaces with mdash string or has been set nil
else
one = mask; -- replace name with mask text (must include name-list separator)
sep_one = " "; -- modify name-list separator
end
else
one = person.last; -- get surname
local first = person.first -- get given name
if utilities.is_set (first) then
if ("vanc" == format) then -- if Vancouver format
one = one:gsub ('%.', ''); -- remove periods from surnames (http://www.ncbi.nlm.nih.gov/books/NBK7271/box/A35029/)
if not person.corporate and is_good_vanc_name (one, first, nil, i) then -- and name is all Latin characters; corporate authors not tested
first = reduce_to_initials (first, i); -- attempt to convert first name(s) to initials
end
end
one = one .. namesep .. first;
end
end
if utilities.is_set (person.link) then
one = utilities.make_wikilink (person.link, one); -- link author/editor
end
if one then -- if <one> has a value (name, mdash replacement, or mask text replacement)
local proj, tag = interwiki_prefixen_get (one, true); -- get the interwiki prefixen if present
if 'w' == proj and ('Wikipedia' == mw.site.namespaces.Project['name']) then
proj = nil; -- for stuff like :w:de:<article>, :w is unnecessary TODO: maint cat?
end
if proj then
proj = ({['d'] = 'Wikidata', ['s'] = 'Wikisource', ['w'] = 'Wikipedia'})[proj]; -- :w (wikipedia) for linking from a non-wikipedia project
if proj then
one = one .. utilities.wrap_style ('interproj', proj); -- add resized leading space, brackets, static text, language name
tag = nil; -- unset; don't do both project and language
end
end
if tag == cfg.this_wiki_code then
tag = nil; -- stuff like :en:<article> at en.wiki is pointless TODO: maint cat?
end
if tag then
local lang = cfg.lang_tag_remap[tag] or cfg.mw_languages_by_tag_t[tag];
if lang then -- error messaging done in extract_names() where we know parameter names
one = one .. utilities.wrap_style ('interwiki', lang); -- add resized leading space, brackets, static text, language name
end
end
table.insert (name_list, one); -- add it to the list of names
table.insert (name_list, sep_one); -- add the proper name-list separator
end
end
end
local count = #name_list / 2; -- (number of names + number of separators) divided by 2
if 0 < count then
if 1 < count and not etal then
if 'amp' == format then
name_list[#name_list-2] = " & "; -- replace last separator with ampersand text
elseif 'and' == format then
if 2 == count then
name_list[#name_list-2] = cfg.presentation.sep_nl_and; -- replace last separator with 'and' text
else
name_list[#name_list-2] = cfg.presentation.sep_nl_end; -- replace last separator with '(sep) and' text
end
end
end
name_list[#name_list] = nil; -- erase the last separator
end
local result = table.concat (name_list); -- construct list
if etal and utilities.is_set (result) then -- etal may be set by |display-authors=etal but we might not have a last-first list
result = result .. sep .. cfg.messages['et al']; -- we've got a last-first list and etal so add et al.
end
return result, count; -- return name-list string and count of number of names (count used for editor names only)
end
--[[--------------------< M A K E _ C I T E R E F _ I D >-----------------------
Generates a CITEREF anchor ID if we have at least one name or a date. Otherwise
returns an empty string.
namelist is one of the contributor-, author-, or editor-name lists chosen in that
order. year is Year or anchor_year.
]]
local function make_citeref_id (namelist, year)
local names={}; -- a table for the one to four names and year
for i,v in ipairs (namelist) do -- loop through the list and take up to the first four last names
names[i] = v.last
if i == 4 then break end -- if four then done
end
table.insert (names, year); -- add the year at the end
local id = table.concat(names); -- concatenate names and year for CITEREF id
if utilities.is_set (id) then -- if concatenation is not an empty string
return "CITEREF" .. id; -- add the CITEREF portion
else
return ''; -- return an empty string; no reason to include CITEREF id in this citation
end
end
--[[--------------------------< C I T E _ C L A S S _A T T R I B U T E _M A K E >------------------------------
construct <cite> tag class attribute for this citation.
<cite_class> – config.CitationClass from calling template
<mode> – value from |mode= parameter
]]
local function cite_class_attribute_make (cite_class, mode)
local class_t = {};
table.insert (class_t, 'citation'); -- required for blue highlight
if 'citation' ~= cite_class then
table.insert (class_t, cite_class); -- identify this template for user css
table.insert (class_t, utilities.is_set (mode) and mode or 'cs1'); -- identify the citation style for user css or javascript
else
table.insert (class_t, utilities.is_set (mode) and mode or 'cs2'); -- identify the citation style for user css or javascript
end
for _, prop_key in ipairs (z.prop_keys_t) do
table.insert (class_t, prop_key); -- identify various properties for user css or javascript
end
return table.concat (class_t, ' '); -- make a big string and done
end
--[[---------------------< N A M E _ H A S _ E T A L >--------------------------
Evaluates the content of name parameters (author, editor, etc.) for variations on
the theme of et al. If found, the et al. is removed, a flag is set to true and
the function returns the modified name and the flag.
This function never sets the flag to false but returns its previous state because
it may have been set by previous passes through this function or by the associated
|display-<names>=etal parameter
]]
local function name_has_etal (name, etal, nocat, param)
if utilities.is_set (name) then -- name can be nil in which case just return
local patterns = cfg.et_al_patterns; -- get patterns from configuration
for _, pattern in ipairs (patterns) do -- loop through all of the patterns
if name:match (pattern) then -- if this 'et al' pattern is found in name
name = name:gsub (pattern, ''); -- remove the offending text
etal = true; -- set flag (may have been set previously here or by |display-<names>=etal)
if not nocat then -- no categorization for |vauthors=
utilities.set_message ('err_etal', {param}); -- and set an error if not added
end
end
end
end
return name, etal;
end
--[[---------------------< N A M E _ I S _ N U M E R I C >----------------------
Add an error message and category when <name> parameter value does not contain letters.
Add a maintenance category when <name> parameter value has numeric characters mixed with characters that are
not numeric characters; could be letters and/or punctuation characters.
This function will only emit one error and one maint message for the current template. Does not emit both error
and maint messages/categories for the same parameter value.
]]
local function name_is_numeric (name, name_alias, list_name)
local patterns = {
'^%D+%d', -- <name> must have digits preceded by other characters
'^%D*%d+%D+', -- <name> must have digits followed by other characters
}
if not added_numeric_name_errs and mw.ustring.match (name, '^[%A]+$') then -- if we have not already set an error message and <name> does not have any alpha characters
utilities.set_message ('err_numeric_names', name_alias); -- add an error message
added_numeric_name_errs = true; -- set the flag so we emit only one error message
return; -- when here no point in further testing; abandon
end
if not added_numeric_name_maint then -- if we have already set a maint message
for _, pattern in ipairs (patterns) do -- spin through list of patterns
if mw.ustring.match (name, pattern) then -- digits preceded or followed by anything but digits; %D+ includes punctuation
utilities.set_message ('maint_numeric_names', cfg.special_case_translation [list_name]); -- add a maint cat for this template
added_numeric_name_maint = true; -- set the flag so we emit only one maint message
return; -- when here no point in further testing; abandon
end
end
end
end
--[[-----------------< N A M E _ H A S _ M U L T _ N A M E S >------------------
Evaluates the content of last/surname (authors etc.) parameters for multiple names.
Multiple names are indicated if there is more than one comma or any "unescaped"
semicolons. Escaped semicolons are ones used as part of selected HTML entities.
If the condition is met, the function adds the multiple name maintenance category.
Same test for first except that commas should not appear in given names (MOS:JR says
that the generational suffix does not take a separator character). Titles, degrees,
postnominals, affiliations, all normally comma separated don't belong in a citation.
<name> – name parameter value
<list_name> – AuthorList, EditorList, etc
<limit> – number of allowed commas; 1 (default) for surnames; 0 for given names
returns nothing
]]
local function name_has_mult_names (name, list_name, limit)
local _, commas, semicolons, nbsps;
limit = limit and limit or 1;
if utilities.is_set (name) then
_, commas = name:gsub (',', ''); -- count the number of commas
_, semicolons = name:gsub (';', ''); -- count the number of semicolons
-- nbsps probably should be its own separate count rather than merged in
-- some way with semicolons because Lua patterns do not support the
-- grouping operator that regex does, which means there is no way to add
-- more entities to escape except by adding more counts with the new
-- entities
_, nbsps = name:gsub (' ',''); -- count nbsps
-- There is exactly 1 semicolon per entity, so subtract nbsps
-- from semicolons to 'escape' them. If additional entities are added,
-- they also can be subtracted.
if limit < commas or 0 < (semicolons - nbsps) then
utilities.set_message ('maint_mult_names', cfg.special_case_translation [list_name]); -- add a maint message
end
end
end
--[=[-------------------------< I S _ G E N E R I C >----------------------------------------------------------
Compares values assigned to various parameters according to the string provided as <item> in the function call.
<item> can have on of two values:
'generic_names' – for name-holding parameters: |last=, |first=, |editor-last=, etc
'generic_titles' – for |title=
There are two types of generic tests. The 'accept' tests look for a pattern that should not be rejected by the
'reject' test. For example,
|author=[[John Smith (author)|Smith, John]]
would be rejected by the 'author' reject test. But piped wikilinks with 'author' disambiguation should not be
rejected so the 'accept' test prevents that from happening. Accept tests are always performed before reject
tests.
Each of the 'accept' and 'reject' sequence tables hold tables for en.wiki (['en']) and local.wiki (['local'])
that each can hold a test sequence table The sequence table holds, at index [1], a test pattern, and, at index
[2], a boolean control value. The control value tells string.find() or mw.ustring.find() to do plain-text search (true)
or a pattern search (false). The intent of all this complexity is to make these searches as fast as possible so
that we don't run out of processing time on very large articles.
Returns
true when a reject test finds the pattern or string
false when an accept test finds the pattern or string
nil else
]=]
local function is_generic (item, value, wiki)
local test_val;
local str_lower = { -- use string.lower() for en.wiki (['en']) and use mw.ustring.lower() or local.wiki (['local'])
['en'] = string.lower,
['local'] = mw.ustring.lower,
}
local str_find = { -- use string.find() for en.wiki (['en']) and use mw.ustring.find() or local.wiki (['local'])
['en'] = string.find,
['local'] = mw.ustring.find,
}
local function test (val, test_t, wiki) -- local function to do the testing; <wiki> selects lower() and find() functions
val = test_t[2] and str_lower[wiki](value) or val; -- when <test_t[2]> set to 'true', plaintext search using lowercase value
return str_find[wiki] (val, test_t[1], 1, test_t[2]); -- return nil when not found or matched
end
local test_types_t = {'accept', 'reject'}; -- test accept patterns first, then reject patterns
local wikis_t = {'en', 'local'}; -- do tests for each of these keys; en.wiki first, local.wiki second
for _, test_type in ipairs (test_types_t) do -- for each test type
for _, generic_value in pairs (cfg.special_case_translation[item][test_type]) do -- spin through the list of generic value fragments to accept or reject
for _, wiki in ipairs (wikis_t) do
if generic_value[wiki] then
if test (value, generic_value[wiki], wiki) then -- go do the test
return ('reject' == test_type); -- param value rejected, return true; false else
end
end
end
end
end
end
--[[--------------------------< N A M E _ I S _ G E N E R I C >------------------------------------------------
calls is_generic() to determine if <name> is a 'generic name' listed in cfg.generic_names; <name_alias> is the
parameter name used in error messaging
]]
local function name_is_generic (name, name_alias)
if not added_generic_name_errs and is_generic ('generic_names', name) then
utilities.set_message ('err_generic_name', name_alias); -- set an error message
added_generic_name_errs = true;
end
end
--[[--------------------------< N A M E _ C H E C K S >--------------------------------------------------------
This function calls various name checking functions used to validate the content of the various name-holding parameters.
]]
local function name_checks (last, first, list_name, last_alias, first_alias)
local accept_name;
if utilities.is_set (last) then
last, accept_name = utilities.has_accept_as_written (last); -- remove accept-this-as-written markup when it wraps all of <last>
if not accept_name then -- <last> not wrapped in accept-as-written markup
name_has_mult_names (last, list_name); -- check for multiple names in the parameter
name_is_numeric (last, last_alias, list_name); -- check for names that have no letters or are a mix of digits and other characters
name_is_generic (last, last_alias); -- check for names found in the generic names list
end
end
if utilities.is_set (first) then
first, accept_name = utilities.has_accept_as_written (first); -- remove accept-this-as-written markup when it wraps all of <first>
if not accept_name then -- <first> not wrapped in accept-as-written markup
name_has_mult_names (first, list_name, 0); -- check for multiple names in the parameter; 0 is number of allowed commas in a given name
name_is_numeric (first, first_alias, list_name); -- check for names that have no letters or are a mix of digits and other characters
name_is_generic (first, first_alias); -- check for names found in the generic names list
end
local wl_type, D = utilities.is_wikilink (first);
if 0 ~= wl_type then
first = D;
utilities.set_message ('err_bad_paramlink', first_alias);
end
end
return last, first; -- done
end
--[[----------------------< E X T R A C T _ N A M E S >-------------------------
Gets name list from the input arguments
Searches through args in sequential order to find |lastn= and |firstn= parameters
(or their aliases), and their matching link and mask parameters. Stops searching
when both |lastn= and |firstn= are not found in args after two sequential attempts:
found |last1=, |last2=, and |last3= but doesn't find |last4= and |last5= then the
search is done.
This function emits an error message when there is a |firstn= without a matching
|lastn=. When there are 'holes' in the list of last names, |last1= and |last3=
are present but |last2= is missing, an error message is emitted. |lastn= is not
required to have a matching |firstn=.
When an author or editor parameter contains some form of 'et al.', the 'et al.'
is stripped from the parameter and a flag (etal) returned that will cause list_people()
to add the static 'et al.' text from Module:Citation/CS1/Configuration. This keeps
'et al.' out of the template's metadata. When this occurs, an error is emitted.
]]
local function extract_names(args, list_name)
local names = {}; -- table of names
local last; -- individual name components
local first;
local link;
local mask;
local i = 1; -- loop counter/indexer
local n = 1; -- output table indexer
local count = 0; -- used to count the number of times we haven't found a |last= (or alias for authors, |editor-last or alias for editors)
local etal = false; -- return value set to true when we find some form of et al. in an author parameter
local last_alias, first_alias, link_alias; -- selected parameter aliases used in error messaging
while true do
last, last_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'err_redundant_parameters', i ); -- search through args for name components beginning at 1
first, first_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'err_redundant_parameters', i );
link, link_alias = utilities.select_one ( args, cfg.aliases[list_name .. '-Link'], 'err_redundant_parameters', i );
mask = utilities.select_one ( args, cfg.aliases[list_name .. '-Mask'], 'err_redundant_parameters', i );
if last then -- error check |lastn= alias for unknown interwiki link prefix; done here because this is where we have the parameter name
local project, language = interwiki_prefixen_get (last, true); -- true because we expect interwiki links in |lastn= to be wikilinked
if nil == project and nil == language then -- when both are nil
utilities.set_message ('err_bad_paramlink', last_alias); -- not known, emit an error message -- TODO: err_bad_interwiki?
last = utilities.remove_wiki_link (last); -- remove wikilink markup; show display value only
end
end
if link then -- error check |linkn= alias for unknown interwiki link prefix
local project, language = interwiki_prefixen_get (link, false); -- false because wiki links in |author-linkn= is an error
if nil == project and nil == language then -- when both are nil
utilities.set_message ('err_bad_paramlink', link_alias); -- not known, emit an error message -- TODO: err_bad_interwiki?
link = nil; -- unset so we don't link
link_alias = nil;
end
end
last, etal = name_has_etal (last, etal, false, last_alias); -- find and remove variations on et al.
first, etal = name_has_etal (first, etal, false, first_alias); -- find and remove variations on et al.
last, first = name_checks (last, first, list_name, last_alias, first_alias); -- multiple names, extraneous annotation, etc. checks
if first and not last then -- if there is a firstn without a matching lastn
local alias = first_alias:find ('given', 1, true) and 'given' or 'first'; -- get first or given form of the alias
utilities.set_message ('err_first_missing_last', {
first_alias, -- param name of alias missing its mate
first_alias:gsub (alias, {['first'] = 'last', ['given'] = 'surname'}), -- make param name appropriate to the alias form
}); -- add this error message
elseif not first and not last then -- if both firstn and lastn aren't found, are we done?
count = count + 1; -- number of times we haven't found last and first
if 2 <= count then -- two missing names and we give up
break; -- normal exit or there is a two-name hole in the list; can't tell which
end
else -- we have last with or without a first
local result;
link = link_title_ok (link, link_alias, last, last_alias); -- check for improper wiki-markup
if first then
link = link_title_ok (link, link_alias, first, first_alias); -- check for improper wiki-markup
end
names[n] = {last = last, first = first, link = link, mask = mask, corporate = false}; -- add this name to our names list (corporate for |vauthors= only)
n = n + 1; -- point to next location in the names table
if 1 == count then -- if the previous name was missing
utilities.set_message ('err_missing_name', {list_name:match ("(%w+)List"):lower(), i - 1}); -- add this error message
end
count = 0; -- reset the counter, we're looking for two consecutive missing names
end
i = i + 1; -- point to next args location
end
return names, etal; -- all done, return our list of names and the etal flag
end
--[[--------------------------< N A M E _ T A G _ G E T >------------------------------------------------------
attempt to decode |language=<lang_param> and return language name and matching tag; nil else.
This function looks for:
<lang_param> as a tag in cfg.lang_tag_remap{}
<lang_param> as a name in cfg.lang_name_remap{}
<lang_param> as a name in cfg.mw_languages_by_name_t
<lang_param> as a tag in cfg.mw_languages_by_tag_t
when those fail, presume that <lang_param> is an IETF-like tag that MediaWiki does not recognize. Strip all
script, region, variant, whatever subtags from <lang_param> to leave just a two or three character language tag
and look for the new <lang_param> in cfg.mw_languages_by_tag_t{}
on success, returns name (in properly capitalized form) and matching tag (in lowercase); on failure returns nil
]]
local function name_tag_get (lang_param)
local lang_param_lc = mw.ustring.lower (lang_param); -- use lowercase as an index into the various tables
local name;
local tag;
name = cfg.lang_tag_remap[lang_param_lc]; -- assume <lang_param_lc> is a tag; attempt to get remapped language name
if name then -- when <name>, <lang_param> is a tag for a remapped language name
if cfg.lang_name_remap[name:lower()][2] ~= lang_param_lc then
utilities.set_message ('maint_unknown_lang'); -- add maint category if not already added
return name, cfg.lang_name_remap[name:lower()][2]; -- so return name and tag from lang_name_remap[name]; special case to xlate sr-ec and sr-el to sr-cyrl and sr-latn
end
return name, lang_param_lc; -- so return <name> from remap and <lang_param_lc>
end
tag = lang_param_lc:match ('^(%a%a%a?)%-.*'); -- still assuming that <lang_param_lc> is a tag; strip script, region, variant subtags
name = cfg.lang_tag_remap[tag]; -- attempt to get remapped language name with language subtag only
if name then -- when <name>, <tag> is a tag for a remapped language name
return name, tag; -- so return <name> from remap and <tag>
end
if cfg.lang_name_remap[lang_param_lc] then -- not a remapped tag, assume <lang_param_lc> is a name; attempt to get remapped language tag
return cfg.lang_name_remap[lang_param_lc][1], cfg.lang_name_remap[lang_param_lc][2]; -- for this <lang_param_lc>, return a (possibly) new name and appropriate tag
end
name = cfg.mw_languages_by_tag_t[lang_param_lc]; -- assume that <lang_param_lc> is a tag; attempt to get its matching language name
if name then
return name, lang_param_lc; -- <lang_param_lc> is a tag so return it and <name>
end
tag = cfg.mw_languages_by_name_t[lang_param_lc]; -- assume that <lang_param_lc> is a language name; attempt to get its matching tag
if tag then
return cfg.mw_languages_by_tag_t[tag], tag; -- <lang_param_lc> is a name so return the name from the table and <tag>
end
tag = lang_param_lc:match ('^(%a%a%a?)%-.*'); -- is <lang_param_lc> an IETF-like tag that MediaWiki doesn't recognize? <tag> gets the language subtag; nil else
if tag then
name = cfg.mw_languages_by_tag_t[tag]; -- attempt to get a language name using the shortened <tag>
if name then
return name, tag; -- <lang_param_lc> is an unrecognized IETF-like tag so return <name> and language subtag
end
end
end
--[[-------------------< L A N G U A G E _ P A R A M E T E R >------------------
Gets language name from a provided two- or three-character ISO 639 code. If a code
is recognized by MediaWiki, use the returned name; if not, then use the value that
was provided with the language parameter.
When |language= contains a recognized language (either code or name), the page is
assigned to the category for that code: Category:Norwegian-language sources (no).
For valid three-character code languages, the page is assigned to the single category
for '639-2' codes: Category:CS1 ISO 639-2 language sources.
Languages that are the same as the local wiki are not categorized. MediaWiki does
not recognize three-character equivalents of two-character codes: code 'ar' is
recognized but code 'ara' is not.
This function supports multiple languages in the form |language=nb, French, th
where the language names or codes are separated from each other by commas with
optional space characters.
]]
local function language_parameter (lang)
local tag; -- some form of IETF-like language tag; language subtag with optional region, sript, vatiant, etc subtags
local lang_subtag; -- ve populates |language= with mostly unecessary region subtags the MediaWiki does not recognize; this is the base language subtag
local name; -- the language name
local language_list = {}; -- table of language names to be rendered
local names_t = {}; -- table made from the value assigned to |language=
local this_wiki_name = mw.language.fetchLanguageName (cfg.this_wiki_code, cfg.this_wiki_code); -- get this wiki's language name
names_t = mw.text.split (lang, '%s*,%s*'); -- names should be a comma separated list
for _, lang in ipairs (names_t) do -- reuse lang here because we don't yet know if lang is a language name or a language tag
local fromEnglishToCode = { -- костыль для РУВИКИ: замена распространённых англоназваний на коды, в следующей итерации использовать Module:Language.
['Arabic'] = 'ar',
['Azerbaijani'] = 'az',
['Belarusian'] = 'be',
['Bulgarian'] = 'bg',
['Czech'] = 'cs',
['Danish'] = 'da',
['German'] = 'de',
['Greek'] = 'el',
['Spanish'] = 'es',
['English'] = 'en',
['Finnish'] = 'fi',
['French'] = 'fr',
['Hebrew'] = 'he',
['Croatian'] = 'hr',
['Hungarian'] = 'hu',
['Armenian'] = 'hy',
['Indonesian'] = 'id',
['Italian'] = 'it',
['Japanese'] = 'ja',
['Korean'] = 'ko',
['Latin'] = 'la',
['Dutch'] = 'nl',
['Norwegian'] = 'no',
['Polish'] = 'pl',
['Portuguese'] = 'pt',
['Romanian'] = 'ro',
['Russian'] = 'ru',
['Slovenian'] = 'sl',
['Serbian'] = 'sr',
['Swedish'] = 'sv',
['Thai'] = 'th',
['Turkish'] = 'tr',
['Ukrainian'] = 'uk',
['Chinese'] = 'zh',
}
if fromEnglishToCode[lang] then
lang = fromEnglishToCode[lang]
end
name, tag = name_tag_get (lang); -- attempt to get name/tag pair for <lang>; <name> has proper capitalization; <tag> is lowercase
if utilities.is_set (tag) then
lang_subtag = tag:gsub ('^(%a%a%a?)%-.*', '%1'); -- for categorization, strip any IETF-like tags from language tag
if cfg.this_wiki_code ~= lang_subtag then -- when the language is not the same as this wiki's language
if 2 == lang_subtag:len() then -- and is a two-character tag
utilities.add_prop_cat ('foreign-lang-source', {name, tag}, lang_subtag); -- categorize it; tag appended to allow for multiple language categorization
else -- or is a recognized language (but has a three-character tag)
utilities.add_prop_cat ('foreign-lang-source-2', {lang_subtag}, lang_subtag); -- categorize it differently TODO: support multiple three-character tag categories per cs1|2 template?
end
elseif cfg.local_lang_cat_enable then -- when the language and this wiki's language are the same and categorization is enabled
utilities.add_prop_cat ('local-lang-source', {name, lang_subtag}); -- categorize it
end
else
name = lang; -- return whatever <lang> has so that we show something
utilities.set_message ('maint_unknown_lang'); -- add maint category if not already added
end
table.insert (language_list, name);
name = ''; -- so we can reuse it
end
name = utilities.make_sep_list (#language_list, language_list);
if (1 == #language_list) and (lang_subtag == cfg.this_wiki_code) then -- when only one language, find lang name in this wiki lang name; for |language=en-us, 'English' in 'American English'
return ''; -- if one language and that language is this wiki's return an empty string (no annotation)
end
return (mw.getCurrentFrame():expandTemplate{ -- РУВИКИ: используем шаблон для отображения языка
title= utilities.substitute (cfg.messages ['language'], tag)
}); -- otherwise wrap with '(in ...)'
--[[ TODO: should only return blank or name rather than full list
so we can clean up the bunched parenthetical elements Language, Type, Format
]]
end
--[[-----------------------< S E T _ C S _ S T Y L E >--------------------------
Gets the default CS style configuration for the given mode.
Returns default separator and either postscript as passed in or the default.
In CS1, the default postscript and separator are '.'.
In CS2, the default postscript is the empty string and the default separator is ','.
]]
local function set_cs_style (postscript, mode)
if utilities.is_set(postscript) then
-- emit a maintenance message if user postscript is the default cs1 postscript
-- we catch the opposite case for cs2 in set_style
if mode == 'cs1' and postscript == cfg.presentation['ps_' .. mode] then
utilities.set_message ('maint_postscript');
end
else
postscript = cfg.presentation['ps_' .. mode];
end
return cfg.presentation['sep_' .. mode], postscript;
end
--[[--------------------------< S E T _ S T Y L E >-----------------------------
Sets the separator and postscript styles. Checks the |mode= first and the
#invoke CitationClass second. Removes the postscript if postscript == none.
]]
local function set_style (mode, postscript, cite_class)
local sep;
if 'cs2' == mode then
sep, postscript = set_cs_style (postscript, 'cs2');
elseif 'cs1' == mode then
sep, postscript = set_cs_style (postscript, 'cs1');
elseif 'citation' == cite_class then
sep, postscript = set_cs_style (postscript, 'cs2');
else
sep, postscript = set_cs_style (postscript, 'cs1');
end
if cfg.keywords_xlate[postscript:lower()] == 'none' then
-- emit a maintenance message if user postscript is the default cs2 postscript
-- we catch the opposite case for cs1 in set_cs_style
if 'cs2' == mode or ('cs1' ~= mode and 'citation' == cite_class) then -- {{citation |title=Title |mode=cs1 |postscript=none}} should not emit maint message
utilities.set_message ('maint_postscript');
end
postscript = '';
end
return sep, postscript
end
--[=[-------------------------< I S _ P D F >-----------------------------------
Determines if a URL has the file extension that is one of the PDF file extensions
used by [[MediaWiki:Common.css]] when applying the PDF icon to external links.
returns true if file extension is one of the recognized extensions, else false
]=]
local function is_pdf (url)
return url:match ('%.pdf$') or url:match ('%.PDF$') or
url:match ('%.pdf[%?#]') or url:match ('%.PDF[%?#]') or
url:match ('%.PDF#') or url:match ('%.pdf#');
end
--[[--------------------------< S T Y L E _ F O R M A T >-----------------------
Applies CSS style to |format=, |chapter-format=, etc. Also emits an error message
if the format parameter does not have a matching URL parameter. If the format parameter
is not set and the URL contains a file extension that is recognized as a PDF document
by MediaWiki's commons.css, this code will set the format parameter to (PDF) with
the appropriate styling.
]]
local function style_format (format, url, fmt_param, url_param)
if utilities.is_set (format) then
format = utilities.wrap_style ('format', format); -- add leading space, parentheses, resize
if not utilities.is_set (url) then
utilities.set_message ('err_format_missing_url', {fmt_param, url_param}); -- add an error message
end
elseif is_pdf (url) then -- format is not set so if URL is a PDF file then
format = utilities.wrap_style ('format', 'PDF'); -- set format to PDF
else
format = ''; -- empty string for concatenation
end
return format;
end
--[[---------------------< G E T _ D I S P L A Y _ N A M E S >------------------
Returns a number that defines the number of names displayed for author and editor
name lists and a Boolean flag to indicate when et al. should be appended to the name list.
When the value assigned to |display-xxxxors= is a number greater than or equal to zero,
return the number and the previous state of the 'etal' flag (false by default
but may have been set to true if the name list contains some variant of the text 'et al.').
When the value assigned to |display-xxxxors= is the keyword 'etal', return a number
that is one greater than the number of authors in the list and set the 'etal' flag true.
This will cause the list_people() to display all of the names in the name list followed by 'et al.'
In all other cases, returns nil and the previous state of the 'etal' flag.
inputs:
max: A['DisplayAuthors'] or A['DisplayEditors'], etc; a number or some flavor of etal
count: #a or #e
list_name: 'authors' or 'editors'
etal: author_etal or editor_etal
This function sets an error message when |display-xxxxors= value greater than or equal to number of names but
not when <max> comes from {{cs1 config}} global settings. When using global settings, <param> is set to the
keyword 'cs1 config' which is used to supress the normal error. Error is suppressed because it is to be expected
that some citations in an article will have the same or fewer names that the limit specified in {{cs1 config}}.
]]
local function get_display_names (max, count, list_name, etal, param)
if utilities.is_set (max) then
if 'etal' == max:lower():gsub("[ '%.]", '') then -- the :gsub() portion makes 'etal' from a variety of 'et al.' spellings and stylings
max = count + 1; -- number of authors + 1 so display all author name plus et al.
etal = true; -- overrides value set by extract_names()
elseif max:match ('^%d+$') then -- if is a string of numbers
max = tonumber (max); -- make it a number
if (max >= count) and ('cs1 config' ~= param) then -- error when local |display-xxxxors= value greater than or equal to number of names; not an error when using global setting
utilities.set_message ('err_disp_name', {param, max}); -- add error message
max = nil;
end
else -- not a valid keyword or number
utilities.set_message ('err_disp_name', {param, max}); -- add error message
max = nil; -- unset; as if |display-xxxxors= had not been set
end
end
return max, etal;
end
--[[----------< E X T R A _ T E X T _ I N _ P A G E _ C H E C K >---------------
Adds error if |page=, |pages=, |quote-page=, |quote-pages= has what appears to be
some form of p. or pp. abbreviation in the first characters of the parameter content.
check page for extraneous p, p., pp, pp., pg, pg. at start of parameter value:
good pattern: '^P[^%.P%l]' matches when page begins PX or P# but not Px
where x and X are letters and # is a digit
bad pattern: '^[Pp][PpGg]' matches when page begins pp, pP, Pp, PP, pg, pG, Pg, PG
]]
local function extra_text_in_page_check (val, name)
if not val:match (cfg.vol_iss_pg_patterns.good_ppattern) then
for _, pattern in ipairs (cfg.vol_iss_pg_patterns.bad_ppatterns) do -- spin through the selected sequence table of patterns
if val:match (pattern) then -- when a match, error so
utilities.set_message ('err_extra_text_pages', name); -- add error message
return; -- and done
end
end
end
end
--[[--------------------------< E X T R A _ T E X T _ I N _ V O L _ I S S _ C H E C K >------------------------
Adds error if |volume= or |issue= has what appears to be some form of redundant 'type' indicator. Applies to
both; this function looks for issue text in both |issue= and |volume= and looks for volume-like text in |voluem=
and |issue=.
For |volume=:
'V.', or 'Vol.' (with or without the dot) abbreviations or 'Volume' in the first characters of the parameter
content (all case insensitive). 'V' and 'v' (without the dot) are presumed to be roman numerals so
are allowed.
For |issue=:
'No.', 'I.', 'Iss.' (with or without the dot) abbreviations, or 'Issue' in the first characters of the
parameter content (all case insensitive); numero styling: 'n°' with degree sign U+00B0, and № precomposed
numero sign U+2116.
Single character values ('v', 'i', 'n') allowed when not followed by separator character ('.', ':', '=', or
whitespace character) – param values are trimmed of whitespace by MediaWiki before delivered to the module.
<val> is |volume= or |issue= parameter value
<name> is |volume= or |issue= parameter name for error message
<selector> is 'v' for |volume=, 'i' for |issue=
sets error message on failure; returns nothing
]]
local function extra_text_in_vol_iss_check (val, name, selector)
if not utilities.is_set (val) then
return;
end
local handler = 'v' == selector and 'err_extra_text_volume' or 'err_extra_text_issue';
val = val:lower(); -- force parameter value to lower case
for _, pattern in ipairs (cfg.vol_iss_pg_patterns.vi_patterns_t) do -- spin through the sequence table of patterns
if val:match (pattern) then -- when a match, error so
utilities.set_message (handler, name); -- add error message
return; -- and done
end
end
end
--[=[-------------------------< G E T _ V _ N A M E _ T A B L E >----------------------------------------------
split apart a |vauthors= or |veditors= parameter. This function allows for corporate names, wrapped in doubled
parentheses to also have commas; in the old version of the code, the doubled parentheses were included in the
rendered citation and in the metadata. Individual author names may be wikilinked
|vauthors=Jones AB, [[E. B. White|White EB]], ((Black, Brown, and Co.))
]=]
local function get_v_name_table (vparam, output_table, output_link_table)
local name_table = mw.text.split(vparam, "%s*,%s*"); -- names are separated by commas
local wl_type, label, link; -- wl_type not used here; just a placeholder
local i = 1;
while name_table[i] do
if name_table[i]:match ('^%(%(.*[^%)][^%)]$') then -- first segment of corporate with one or more commas; this segment has the opening doubled parentheses
local name = name_table[i];
i = i + 1; -- bump indexer to next segment
while name_table[i] do
name = name .. ', ' .. name_table[i]; -- concatenate with previous segments
if name_table[i]:match ('^.*%)%)$') then -- if this table member has the closing doubled parentheses
break; -- and done reassembling so
end
i = i + 1; -- bump indexer
end
table.insert (output_table, name); -- and add corporate name to the output table
table.insert (output_link_table, ''); -- no wikilink
else
wl_type, label, link = utilities.is_wikilink (name_table[i]); -- wl_type is: 0, no wl (text in label variable); 1, [[D]]; 2, [[L|D]]
table.insert (output_table, label); -- add this name
if 1 == wl_type then
table.insert (output_link_table, label); -- simple wikilink [[D]]
else
table.insert (output_link_table, link); -- no wikilink or [[L|D]]; add this link if there is one, else empty string
end
end
i = i + 1;
end
return output_table;
end
--[[--------------------------< P A R S E _ V A U T H O R S _ V E D I T O R S >--------------------------------
This function extracts author / editor names from |vauthors= or |veditors= and finds matching |xxxxor-maskn= and
|xxxxor-linkn= in args. It then returns a table of assembled names just as extract_names() does.
Author / editor names in |vauthors= or |veditors= must be in Vancouver system style. Corporate or institutional names
may sometimes be required and because such names will often fail the is_good_vanc_name() and other format compliance
tests, are wrapped in doubled parentheses ((corporate name)) to suppress the format tests.
Supports generational suffixes Jr, 2nd, 3rd, 4th–6th.
This function sets the Vancouver error when a required comma is missing and when there is a space between an author's initials.
]]
local function parse_vauthors_veditors (args, vparam, list_name)
local names = {}; -- table of names assembled from |vauthors=, |author-maskn=, |author-linkn=
local v_name_table = {};
local v_link_table = {}; -- when name is wikilinked, targets go in this table
local etal = false; -- return value set to true when we find some form of et al. vauthors parameter
local last, first, link, mask, suffix;
local corporate = false;
vparam, etal = name_has_etal (vparam, etal, true); -- find and remove variations on et al. do not categorize (do it here because et al. might have a period)
v_name_table = get_v_name_table (vparam, v_name_table, v_link_table); -- names are separated by commas
for i, v_name in ipairs(v_name_table) do
first = ''; -- set to empty string for concatenation and because it may have been set for previous author/editor
local accept_name;
v_name, accept_name = utilities.has_accept_as_written (v_name); -- remove accept-this-as-written markup when it wraps all of <v_name>
if accept_name then
last = v_name;
corporate = true; -- flag used in list_people()
elseif string.find(v_name, "%s") then
if v_name:find('[;%.]') then -- look for commonly occurring punctuation characters;
add_vanc_error (cfg.err_msg_supl.punctuation, i);
end
local lastfirstTable = {}
lastfirstTable = mw.text.split(v_name, "%s+")
first = table.remove(lastfirstTable); -- removes and returns value of last element in table which should be initials or generational suffix
if not mw.ustring.match (first, '^%u+$') then -- mw.ustring here so that later we will catch non-Latin characters
suffix = first; -- not initials so assume that whatever we got is a generational suffix
first = table.remove(lastfirstTable); -- get what should be the initials from the table
end
last = table.concat(lastfirstTable, ' ') -- returns a string that is the concatenation of all other names that are not initials and generational suffix
if not utilities.is_set (last) then
first = ''; -- unset
last = v_name; -- last empty because something wrong with first
add_vanc_error (cfg.err_msg_supl.name, i);
end
if mw.ustring.match (last, '%a+%s+%u+%s+%a+') then
add_vanc_error (cfg.err_msg_supl['missing comma'], i); -- matches last II last; the case when a comma is missing
end
if mw.ustring.match (v_name, ' %u %u$') then -- this test is in the wrong place TODO: move or replace with a more appropriate test
add_vanc_error (cfg.err_msg_supl.initials, i); -- matches a space between two initials
end
else
last = v_name; -- last name or single corporate name? Doesn't support multiword corporate names? do we need this?
end
if utilities.is_set (first) then
if not mw.ustring.match (first, "^%u?%u$") then -- first shall contain one or two upper-case letters, nothing else
add_vanc_error (cfg.err_msg_supl.initials, i); -- too many initials; mixed case initials (which may be ok Romanization); hyphenated initials
end
is_good_vanc_name (last, first, suffix, i); -- check first and last before restoring the suffix which may have a non-Latin digit
if utilities.is_set (suffix) then
first = first .. ' ' .. suffix; -- if there was a suffix concatenate with the initials
suffix = ''; -- unset so we don't add this suffix to all subsequent names
end
else
if not corporate then
is_good_vanc_name (last, '', nil, i);
end
end
link = utilities.select_one ( args, cfg.aliases[list_name .. '-Link'], 'err_redundant_parameters', i ) or v_link_table[i];
mask = utilities.select_one ( args, cfg.aliases[list_name .. '-Mask'], 'err_redundant_parameters', i );
names[i] = {last = last, first = first, link = link, mask = mask, corporate = corporate}; -- add this assembled name to our names list
end
return names, etal; -- all done, return our list of names
end
--[[--------------------------< S E L E C T _ A U T H O R _ E D I T O R _ S O U R C E >------------------------
Select one of |authors=, |authorn= / |lastn / firstn=, or |vauthors= as the source of the author name list or
select one of |editorn= / editor-lastn= / |editor-firstn= or |veditors= as the source of the editor name list.
Only one of these appropriate three will be used. The hierarchy is: |authorn= (and aliases) highest and |authors= lowest;
|editorn= (and aliases) highest and |veditors= lowest (support for |editors= withdrawn)
When looking for |authorn= / |editorn= parameters, test |xxxxor1= and |xxxxor2= (and all of their aliases); stops after the second
test which mimicks the test used in extract_names() when looking for a hole in the author name list. There may be a better
way to do this, I just haven't discovered what that way is.
Emits an error message when more than one xxxxor name source is provided.
In this function, vxxxxors = vauthors or veditors; xxxxors = authors as appropriate.
]]
local function select_author_editor_source (vxxxxors, xxxxors, args, list_name)
local lastfirst = false;
if utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'none', 1 ) or -- do this twice in case we have a |first1= without a |last1=; this ...
utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'none', 1 ) or -- ... also catches the case where |first= is used with |vauthors=
utilities.select_one ( args, cfg.aliases[list_name .. '-Last'], 'none', 2 ) or
utilities.select_one ( args, cfg.aliases[list_name .. '-First'], 'none', 2 ) then
lastfirst = true;
end
if (utilities.is_set (vxxxxors) and true == lastfirst) or -- these are the three error conditions
(utilities.is_set (vxxxxors) and utilities.is_set (xxxxors)) or
(true == lastfirst and utilities.is_set (xxxxors)) then
local err_name;
if 'AuthorList' == list_name then -- figure out which name should be used in error message
err_name = 'author';
else
err_name = 'editor';
end
utilities.set_message ('err_redundant_parameters', err_name .. '-name-list parameters'); -- add error message
end
if true == lastfirst then return 1 end; -- return a number indicating which author name source to use
if utilities.is_set (vxxxxors) then return 2 end;
if utilities.is_set (xxxxors) then return 3 end;
return 1; -- no authors so return 1; this allows missing author name test to run in case there is a first without last
end
--[[--------------------------< I S _ V A L I D _ P A R A M E T E R _ V A L U E >------------------------------
This function is used to validate a parameter's assigned value for those parameters that have only a limited number
of allowable values (yes, y, true, live, dead, etc.). When the parameter value has not been assigned a value (missing
or empty in the source template) the function returns the value specified by ret_val. If the parameter value is one
of the list of allowed values returns the translated value; else, emits an error message and returns the value
specified by ret_val.
TODO: explain <invert>
]]
local function is_valid_parameter_value (value, name, possible, ret_val, invert)
if not utilities.is_set (value) then
return ret_val; -- an empty parameter is ok
end
if (not invert and utilities.in_array (value, possible)) then -- normal; <value> is in <possible> table
return cfg.keywords_xlate[value]; -- return translation of parameter keyword
elseif invert and not utilities.in_array (value, possible) then -- invert; <value> is not in <possible> table
return value; -- return <value> as it is
else
utilities.set_message ('err_invalid_param_val', {name, value}); -- not an allowed value so add error message
return ret_val;
end
end
--[[--------------------------< T E R M I N A T E _ N A M E _ L I S T >----------------------------------------
This function terminates a name list (author, contributor, editor) with a separator character (sepc) and a space
when the last character is not a sepc character or when the last three characters are not sepc followed by two
closing square brackets (close of a wikilink). When either of these is true, the name_list is terminated with a
single space character.
]]
local function terminate_name_list (name_list, sepc)
if (string.sub (name_list, -3, -1) == sepc .. '. ') then -- if already properly terminated
return name_list; -- just return the name list
elseif (string.sub (name_list, -1, -1) == sepc) or (string.sub (name_list, -3, -1) == sepc .. ']]') then -- if last name in list ends with sepc char
return name_list .. " "; -- don't add another
else
return name_list .. sepc .. ' '; -- otherwise terminate the name list
end
end
--[[-------------------------< F O R M A T _ V O L U M E _ I S S U E >-----------------------------------------
returns the concatenation of the formatted volume and issue (or journal article number) parameters as a single
string; or formatted volume or formatted issue, or an empty string if neither are set.
]]
local function format_volume_issue (volume, issue, article, cite_class, origin, sepc, lower)
if not utilities.is_set (volume) and not utilities.is_set (issue) and not utilities.is_set (article) then
return '';
end
-- same condition as in format_pages_sheets()
local is_journal = 'journal' == cite_class or (utilities.in_array (cite_class, {'citation', 'map', 'interview'}) and 'journal' == origin);
local is_numeric_vol = volume and (volume:match ('^[MDCLXVI]+$') or volume:match ('^%d+$')); -- is only uppercase roman numerals or only digits?
local is_long_vol = volume and (4 < mw.ustring.len(volume)); -- is |volume= value longer than 4 characters?
if volume and (not is_numeric_vol and is_long_vol) then -- when not all digits or Roman numerals, is |volume= longer than 4 characters?
utilities.add_prop_cat ('long-vol'); -- yes, add properties cat
end
if is_journal then -- journal-style formatting
local vol = '';
if utilities.is_set (volume) then
if is_numeric_vol then -- |volume= value all digits or all uppercase Roman numerals?
vol = utilities.substitute (cfg.presentation['vol-bold'], {sepc, volume}); -- render in bold face
elseif is_long_vol then -- not all digits or Roman numerals; longer than 4 characters?
vol = utilities.substitute (cfg.messages['j-vol'], {sepc, utilities.hyphen_to_dash (volume)}); -- not bold
else -- four or fewer characters
vol = utilities.substitute (cfg.presentation['vol-bold'], {sepc, utilities.hyphen_to_dash (volume)}); -- bold
end
end
vol = vol .. (utilities.is_set (issue) and utilities.substitute (cfg.messages['j-issue'], issue) or '')
vol = vol .. (utilities.is_set (article) and utilities.substitute (cfg.messages['j-article-num'], article) or '')
return vol;
end
if 'podcast' == cite_class and utilities.is_set (issue) then
return wrap_msg ('issue', {sepc, issue}, lower);
end
if 'conference' == cite_class and utilities.is_set (article) then -- |article-number= supported only in journal and conference cites
if utilities.is_set (volume) and utilities.is_set (article) then -- both volume and article number
return wrap_msg ('vol-art', {sepc, utilities.hyphen_to_dash (volume), article}, lower);
elseif utilities.is_set (article) then -- article number alone; when volume alone, handled below
return wrap_msg ('art', {sepc, article}, lower);
end
end
-- all other types of citation
if utilities.is_set (volume) and utilities.is_set (issue) then
return wrap_msg ('vol-no', {sepc, utilities.hyphen_to_dash (volume), issue}, lower);
elseif utilities.is_set (volume) then
return wrap_msg ('vol', {sepc, utilities.hyphen_to_dash (volume)}, lower);
else
return wrap_msg ('issue', {sepc, issue}, lower);
end
end
--[[-------------------------< F O R M A T _ P A G E S _ S H E E T S >-----------------------------------------
adds static text to one of |page(s)= or |sheet(s)= values and returns it with all of the others set to empty strings.
The return order is:
page, pages, sheet, sheets
Singular has priority over plural when both are provided.
]]
local function format_pages_sheets (page, pages, sheet, sheets, cite_class, origin, sepc, nopp, lower)
if 'map' == cite_class then -- only cite map supports sheet(s) as in-source locators
if utilities.is_set (sheet) then
if 'journal' == origin then
return '', '', wrap_msg ('j-sheet', sheet, lower), '';
else
return '', '', wrap_msg ('sheet', {sepc, sheet}, lower), '';
end
elseif utilities.is_set (sheets) then
if 'journal' == origin then
return '', '', '', wrap_msg ('j-sheets', sheets, lower);
else
return '', '', '', wrap_msg ('sheets', {sepc, sheets}, lower);
end
end
end
local is_journal = 'journal' == cite_class or (utilities.in_array (cite_class, {'citation', 'map', 'interview'}) and 'journal' == origin);
if utilities.is_set (page) then
if is_journal then
return utilities.substitute (cfg.messages['j-page(s)'], page), '', '', '';
elseif not nopp then
return utilities.substitute (cfg.messages['p-prefix'], {sepc, page}), '', '', '';
else
return utilities.substitute (cfg.messages['nopp'], {sepc, page}), '', '', '';
end
elseif utilities.is_set (pages) then
if is_journal then
return utilities.substitute (cfg.messages['j-page(s)'], pages), '', '', '';
elseif tonumber(pages) ~= nil and not nopp then -- if pages is only digits, assume a single page number
return '', utilities.substitute (cfg.messages['p-prefix'], {sepc, pages}), '', '';
elseif not nopp then
return '', utilities.substitute (cfg.messages['pp-prefix'], {sepc, pages}), '', '';
else
return '', utilities.substitute (cfg.messages['nopp'], {sepc, pages}), '', '';
end
end
return '', '', '', ''; -- return empty strings
end
--[[--------------------------< I N S O U R C E _ L O C _ G E T >----------------------------------------------
returns one of the in-source locators: page, pages, or at.
If any of these are interwiki links to Wikisource, returns the label portion of the interwiki-link as plain text
for use in COinS. This COinS thing is done because here we convert an interwiki-link to an external link and
add an icon span around that; get_coins_pages() doesn't know about the span. TODO: should it?
TODO: add support for sheet and sheets?; streamline;
TODO: make it so that this function returns only one of the three as the single in-source (the return value assigned
to a new name)?
]]
local function insource_loc_get (page, page_orig, pages, pages_orig, at)
local ws_url, ws_label, coins_pages, L; -- for Wikisource interwiki-links; TODO: this corrupts page metadata (span remains in place after cleanup; fix there?)
if utilities.is_set (page) then
if utilities.is_set (pages) or utilities.is_set (at) then
pages = ''; -- unset the others
at = '';
end
extra_text_in_page_check (page, page_orig); -- emit error message when |page= value begins with what looks like p., pp., etc.
ws_url, ws_label, L = wikisource_url_make (page); -- make ws URL from |page= interwiki link; link portion L becomes tooltip label
if ws_url then
page = external_link (ws_url, ws_label .. ' ', 'ws link in page'); -- space char after label to move icon away from in-source text; TODO: a better way to do this?
page = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, page});
coins_pages = ws_label;
end
elseif utilities.is_set (pages) then
if utilities.is_set (at) then
at = ''; -- unset
end
extra_text_in_page_check (pages, pages_orig); -- emit error message when |page= value begins with what looks like p., pp., etc.
ws_url, ws_label, L = wikisource_url_make (pages); -- make ws URL from |pages= interwiki link; link portion L becomes tooltip label
if ws_url then
pages = external_link (ws_url, ws_label .. ' ', 'ws link in pages'); -- space char after label to move icon away from in-source text; TODO: a better way to do this?
pages = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, pages});
coins_pages = ws_label;
end
elseif utilities.is_set (at) then
ws_url, ws_label, L = wikisource_url_make (at); -- make ws URL from |at= interwiki link; link portion L becomes tooltip label
if ws_url then
at = external_link (ws_url, ws_label .. ' ', 'ws link in at'); -- space char after label to move icon away from in-source text; TODO: a better way to do this?
at = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, at});
coins_pages = ws_label;
end
end
return page, pages, at, coins_pages;
end
--[[--------------------------< I S _ U N I Q U E _ A R C H I V E _ U R L >------------------------------------
add error message when |archive-url= value is same as |url= or chapter-url= (or alias...) value
]]
local function is_unique_archive_url (archive, url, c_url, source, date)
if utilities.is_set (archive) then
if archive == url or archive == c_url then
utilities.set_message ('err_bad_url', {utilities.wrap_style ('parameter', source)}); -- add error message
return '', ''; -- unset |archive-url= and |archive-date= because same as |url= or |chapter-url=
end
end
return archive, date;
end
--[=[-------------------------< A R C H I V E _ U R L _ C H E C K >--------------------------------------------
Check archive.org URLs to make sure they at least look like they are pointing at valid archives and not to the
save snapshot URL or to calendar pages. When the archive URL is 'https://web.archive.org/save/' (or http://...)
archive.org saves a snapshot of the target page in the URL. That is something that Wikipedia should not allow
unwitting readers to do.
When the archive.org URL does not have a complete timestamp, archive.org chooses a snapshot according to its own
algorithm or provides a calendar 'search' result. [[WP:ELNO]] discourages links to search results.
This function looks at the value assigned to |archive-url= and returns empty strings for |archive-url= and
|archive-date= and an error message when:
|archive-url= holds an archive.org save command URL
|archive-url= is an archive.org URL that does not have a complete timestamp (YYYYMMDDhhmmss 14 digits) in the
correct place
otherwise returns |archive-url= and |archive-date=
There are two mostly compatible archive.org URLs:
//web.archive.org/<timestamp>... -- the old form
//web.archive.org/web/<timestamp>... -- the new form
The old form does not support or map to the new form when it contains a display flag. There are four identified flags
('id_', 'js_', 'cs_', 'im_') but since archive.org ignores others following the same form (two letters and an underscore)
we don't check for these specific flags but we do check the form.
This function supports a preview mode. When the article is rendered in preview mode, this function may return a modified
archive URL:
for save command errors, return undated wildcard (/*/)
for timestamp errors when the timestamp has a wildcard, return the URL unmodified
for timestamp errors when the timestamp does not have a wildcard, return with timestamp limited to six digits plus wildcard (/yyyymm*/)
A secondary function is to return an archive-url timestamp from those urls that have them (archive.org and
archive.today). The timestamp is used by validation.archive_date_check() to see if the value in |archive-date=
matches the timestamp in the archive url.
]=]
local function archive_url_check (url, date)
local err_msg = ''; -- start with the error message empty
local path, timestamp, flag; -- portions of the archive.org URL
timestamp = url:match ('//archive.today/(%d%d%d%d%d%d%d%d%d%d%d%d%d%d)/') or -- get timestamp from archive.today urls
url:match ('//archive.today/(%d%d%d%d%.%d%d%.%d%d%-%d%d%d%d%d%d)/'); -- this timestamp needs cleanup
if timestamp then -- if this was an archive.today url ...
return url, date, timestamp:gsub ('[%.%-]', ''); -- return ArchiveURL, ArchiveDate, and timestamp (dots and dashes removed) from |archive-url=, and done -- return ArchiveURL, ArchiveDate, and timestamp from |archive-url=, and done
end
-- here for archive.org urls
if (not url:match('//web%.archive%.org/')) and (not url:match('//liveweb%.archive%.org/')) then -- also deprecated liveweb Wayback machine URL
return url, date; -- not an archive.org archive, return ArchiveURL and ArchiveDate
end
if url:match('//web%.archive%.org/save/') then -- if a save command URL, we don't want to allow saving of the target page
err_msg = cfg.err_msg_supl.save;
url = url:gsub ('(//web%.archive%.org)/save/', '%1/*/', 1); -- for preview mode: modify ArchiveURL
elseif url:match('//liveweb%.archive%.org/') then
err_msg = cfg.err_msg_supl.liveweb;
else
path, timestamp, flag = url:match('//web%.archive%.org/([^%d]*)(%d+)([^/]*)/'); -- split out some of the URL parts for evaluation
if not path then -- malformed in some way; pattern did not match
err_msg = cfg.err_msg_supl.timestamp;
elseif 14 ~= timestamp:len() then -- path and flag optional, must have 14-digit timestamp here
err_msg = cfg.err_msg_supl.timestamp;
if '*' ~= flag then
local replacement = timestamp:match ('^%d%d%d%d%d%d') or timestamp:match ('^%d%d%d%d'); -- get the first 6 (YYYYMM) or first 4 digits (YYYY)
if replacement then -- nil if there aren't at least 4 digits (year)
replacement = replacement .. string.rep ('0', 14 - replacement:len()); -- year or yearmo (4 or 6 digits) zero-fill to make 14-digit timestamp
url=url:gsub ('(//web%.archive%.org/[^%d]*)%d[^/]*', '%1' .. replacement .. '*', 1) -- for preview, modify ts to 14 digits plus splat for calendar display
end
end
elseif utilities.is_set (path) and 'web/' ~= path then -- older archive URLs do not have the extra 'web/' path element
err_msg = cfg.err_msg_supl.path;
elseif utilities.is_set (flag) and not utilities.is_set (path) then -- flag not allowed with the old form URL (without the 'web/' path element)
err_msg = cfg.err_msg_supl.flag;
elseif utilities.is_set (flag) and not flag:match ('%a%a_') then -- flag if present must be two alpha characters and underscore (requires 'web/' path element)
err_msg = cfg.err_msg_supl.flag;
else
return url, date, timestamp; -- return ArchiveURL, ArchiveDate, and timestamp from |archive-url=
end
end
-- if here, something not right so
utilities.set_message ('err_archive_url', {err_msg}); -- add error message and
if is_preview_mode then
return url, date, timestamp; -- preview mode so return ArchiveURL, ArchiveDate, and timestamp from |archive-url=
else
return '', ''; -- return empty strings for ArchiveURL and ArchiveDate
end
end
--[[--------------------------< P L A C E _ C H E C K >--------------------------------------------------------
check |place=, |publication-place=, |location= to see if these params include digits. This function added because
many editors misuse location to specify the in-source location (|page(s)= and |at= are supposed to do that)
returns the original parameter value without modification; added maint cat when parameter value contains digits
]]
local function place_check (param_val)
if not utilities.is_set (param_val) then -- parameter empty or omitted
return param_val; -- return that empty state
end
if mw.ustring.find (param_val, '%d') then -- not empty, are there digits in the parameter value
utilities.set_message ('maint_location'); -- yep, add maint cat
end
return param_val; -- and done
end
--[[--------------------------< I S _ A R C H I V E D _ C O P Y >----------------------------------------------
compares |title= to 'Archived copy' (placeholder added by bots that can't find proper title); if matches, return true; nil else
]]
local function is_archived_copy (title)
title = mw.ustring.lower(title); -- switch title to lower case
if title:find (cfg.special_case_translation.archived_copy.en) then -- if title is 'Archived copy'
return true;
elseif cfg.special_case_translation.archived_copy['local'] then
if mw.ustring.find (title, cfg.special_case_translation.archived_copy['local']) then -- mw.ustring() because might not be Latin script
return true;
end
end
end
--[[--------------------------< D I S P L A Y _ N A M E S _ S E L E C T >--------------------------------------
for any of the |display-authors=, |display-editors=, etc parameters, select either the local or global setting.
When both are present, look at <local_display_names> value. When the value is some sort of 'et al.'string,
special handling is required.
When {{cs1 config}} has |display-<namelist>= AND this template has |display-<namelist>=etal AND:
the number of names specified by <number_of_names> is:
greater than the number specified in the global |display-<namelist>= parameter (<global_display_names>)
use global |display-<namelist>= parameter value
set overridden maint category
less than or equal to the number specified in the global |display-<namelist>= parameter
use local |display-<namelist>= parameter value
The purpose of this function is to prevent categorizing a template that has fewer names than the global setting
to keep the etal annotation specified by <local_display_names>.
]]
local function display_names_select (global_display_names, local_display_names, param_name, number_of_names, test)
if global_display_names and utilities.is_set (local_display_names) then -- when both
if 'etal' == local_display_names:lower():gsub("[ '%.]", '') then -- the :gsub() portion makes 'etal' from a variety of 'et al.' spellings and stylings
number_of_names = tonumber (number_of_names); -- convert these to numbers for comparison
local global_display_names_num = tonumber (global_display_names); -- <global_display_names> not set when parameter value is not digits
if number_of_names > global_display_names_num then -- template has more names than global config allows to be displayed?
utilities.set_message ('maint_overridden_setting'); -- set a maint message because global is overriding local |display-<namelist>=etal
return global_display_names, 'cs1 config'; -- return global with spoof parameter name (for get_display_names())
else
return local_display_names, param_name; -- return local because fewer names so let <local_display_names> control
end
end
-- here when <global_display_names> and <local_display_names> both numbers; <global_display_names> controls
utilities.set_message ('maint_overridden_setting'); -- set a maint message
return global_display_names, 'cs1 config'; -- return global with spoof parameter name (for get_display_names())
end
-- here when only one of <global_display_names> or <local_display_names> set
if global_display_names then
return global_display_names, 'cs1 config'; -- return global with spoof parameter name (for get_display_names())
else
return local_display_names, param_name; -- return local
end
end
--[[--------------------------< C I T A T I O N 0 >------------------------------------------------------------
This is the main function doing the majority of the citation formatting.
]]
local function citation0( config, args )
--[[
Load Input Parameters
The argument_wrapper facilitates the mapping of multiple aliases to single internal variable.
]]
local A = argument_wrapper ( args );
local i
-- Pick out the relevant fields from the arguments. Different citation templates
-- define different field names for the same underlying things.
local author_etal;
local a = {}; -- authors list from |lastn= / |firstn= pairs or |vauthors=
local Authors;
local NameListStyle;
if cfg.global_cs1_config_t['NameListStyle'] then -- global setting in {{cs1 config}} overrides local |name-list-style= parameter value; nil when empty or assigned value invalid
NameListStyle = is_valid_parameter_value (cfg.global_cs1_config_t['NameListStyle'], 'cs1 config: name-list-style', cfg.keywords_lists['name-list-style'], ''); -- error messaging 'param' here is a hoax
else
NameListStyle = is_valid_parameter_value (A['NameListStyle'], A:ORIGIN('NameListStyle'), cfg.keywords_lists['name-list-style'], '');
end
if cfg.global_cs1_config_t['NameListStyle'] and utilities.is_set (A['NameListStyle']) then -- when template has |name-list-style=<something> which global setting has overridden
utilities.set_message ('maint_overridden_setting'); -- set a maint message
end
local Collaboration = A['Collaboration'];
do -- to limit scope of selected
local selected = select_author_editor_source (A['Vauthors'], A['Authors'], args, 'AuthorList');
if 1 == selected then
a, author_etal = extract_names (args, 'AuthorList'); -- fetch author list from |authorn= / |lastn= / |firstn=, |author-linkn=, and |author-maskn=
elseif 2 == selected then
NameListStyle = 'vanc'; -- override whatever |name-list-style= might be
a, author_etal = parse_vauthors_veditors (args, A['Vauthors'], 'AuthorList'); -- fetch author list from |vauthors=, |author-linkn=, and |author-maskn=
elseif 3 == selected then
Authors = A['Authors']; -- use content of |authors=
end
if utilities.is_set (Collaboration) then
author_etal = true; -- so that |display-authors=etal not required
end
end
local editor_etal;
local e = {}; -- editors list from |editor-lastn= / |editor-firstn= pairs or |veditors=
do -- to limit scope of selected
local selected = select_author_editor_source (A['Veditors'], nil, args, 'EditorList'); -- support for |editors= withdrawn
if 1 == selected then
e, editor_etal = extract_names (args, 'EditorList'); -- fetch editor list from |editorn= / |editor-lastn= / |editor-firstn=, |editor-linkn=, and |editor-maskn=
elseif 2 == selected then
NameListStyle = 'vanc'; -- override whatever |name-list-style= might be
e, editor_etal = parse_vauthors_veditors (args, args.veditors, 'EditorList'); -- fetch editor list from |veditors=, |editor-linkn=, and |editor-maskn=
end
end
local Chapter = A['Chapter']; -- done here so that we have access to |contribution= from |chapter= aliases
local Chapter_origin = A:ORIGIN ('Chapter');
local Contribution; -- because contribution is required for contributor(s)
if 'contribution' == Chapter_origin then
Contribution = Chapter; -- get the name of the contribution
end
local c = {}; -- contributors list from |contributor-lastn= / contributor-firstn= pairs
if utilities.in_array (config.CitationClass, {"book", "citation"}) and not utilities.is_set (A['Periodical']) then -- |contributor= and |contribution= only supported in book cites
c = extract_names (args, 'ContributorList'); -- fetch contributor list from |contributorn= / |contributor-lastn=, -firstn=, -linkn=, -maskn=
if 0 < #c then
if not utilities.is_set (Contribution) then -- |contributor= requires |contribution=
utilities.set_message ('err_contributor_missing_required_param', 'contribution'); -- add missing contribution error message
c = {}; -- blank the contributors' table; it is used as a flag later
end
if 0 == #a then -- |contributor= requires |author=
utilities.set_message ('err_contributor_missing_required_param', 'author'); -- add missing author error message
c = {}; -- blank the contributors' table; it is used as a flag later
end
end
else -- if not a book cite
if utilities.select_one (args, cfg.aliases['ContributorList-Last'], 'err_redundant_parameters', 1 ) then -- are there contributor name list parameters?
utilities.set_message ('err_contributor_ignored'); -- add contributor ignored error message
end
Contribution = nil; -- unset
end
local Title = A['Title'];
local TitleLink = A['TitleLink'];
local auto_select = ''; -- default is auto
local accept_link;
TitleLink, accept_link = utilities.has_accept_as_written (TitleLink, true); -- test for accept-this-as-written markup
if (not accept_link) and utilities.in_array (TitleLink, {'none', 'pmc', 'doi'}) then -- check for special keywords
auto_select = TitleLink; -- remember selection for later
TitleLink = ''; -- treat as if |title-link= would have been empty
end
TitleLink = link_title_ok (TitleLink, A:ORIGIN ('TitleLink'), Title, 'title'); -- check for wiki-markup in |title-link= or wiki-markup in |title= when |title-link= is set
local Section = ''; -- {{cite map}} only; preset to empty string for concatenation if not used
if 'map' == config.CitationClass and 'section' == Chapter_origin then
Section = A['Chapter']; -- get |section= from |chapter= alias list; |chapter= and the other aliases not supported in {{cite map}}
Chapter = ''; -- unset for now; will be reset later from |map= if present
end
local Periodical = A['Periodical'];
local Periodical_origin = A:ORIGIN('Periodical');
local ScriptPeriodical = A['ScriptPeriodical'];
local ScriptPeriodical_origin = A:ORIGIN('ScriptPeriodical');
local TransPeriodical = A['TransPeriodical'];
local TransPeriodical_origin = A:ORIGIN ('TransPeriodical');
if (utilities.in_array (config.CitationClass, {'book', 'encyclopaedia'}) and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical) or utilities.is_set (TransPeriodical))) then
local param;
if utilities.is_set (Periodical) then -- get a parameter name from one of these periodical related meta-parameters
Periodical = ''; -- unset because not valid {{cite book}} or {{cite encyclopedia}} parameters
param = Periodical_origin -- get parameter name for error messaging
elseif utilities.is_set (TransPeriodical) then
TransPeriodical = ''; -- unset because not valid {{cite book}} or {{cite encyclopedia}} parameters
param = TransPeriodical_origin; -- get parameter name for error messaging
elseif utilities.is_set (ScriptPeriodical) then
ScriptPeriodical = ''; -- unset because not valid {{cite book}} or {{cite encyclopedia}} parameters
param = ScriptPeriodical_origin; -- get parameter name for error messaging
end
if utilities.is_set (param) then -- if we found one
utilities.set_message ('err_periodical_ignored', {param}); -- emit an error message
end
end
if utilities.is_set (Periodical) then
local i;
Periodical, i = utilities.strip_apostrophe_markup (Periodical); -- strip apostrophe markup so that metadata isn't contaminated
if i then -- non-zero when markup was stripped so emit an error message
utilities.set_message ('err_apostrophe_markup', {Periodical_origin});
end
end
if 'mailinglist' == config.CitationClass then -- special case for {{cite mailing list}}
if utilities.is_set (Periodical) and utilities.is_set (A ['MailingList']) then -- both set emit an error TODO: make a function for this and similar?
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', Periodical_origin) .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'mailinglist')});
end
Periodical = A ['MailingList']; -- error or no, set Periodical to |mailinglist= value because this template is {{cite mailing list}}
Periodical_origin = A:ORIGIN('MailingList');
end
-- web and news not tested for now because of
-- Wikipedia:Administrators%27_noticeboard#Is_there_a_semi-automated_tool_that_could_fix_these_annoying_"Cite_Web"_errors?
if not (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) then -- 'periodical' templates require periodical parameter
-- local p = {['journal'] = 'journal', ['magazine'] = 'magazine', ['news'] = 'newspaper', ['web'] = 'website'}; -- for error message
local p = {['journal'] = 'journal', ['magazine'] = 'magazine'}; -- for error message
if p[config.CitationClass] then
utilities.set_message ('err_missing_periodical', {config.CitationClass, p[config.CitationClass]});
end
end
local Volume;
if 'citation' == config.CitationClass then
if utilities.is_set (Periodical) then
if not utilities.in_array (Periodical_origin, cfg.citation_no_volume_t) then -- {{citation}} does not render |volume= when these parameters are used
Volume = A['Volume']; -- but does for all other 'periodicals'
end
elseif utilities.is_set (ScriptPeriodical) then
if 'script-website' ~= ScriptPeriodical_origin then -- {{citation}} does not render volume for |script-website=
Volume = A['Volume']; -- but does for all other 'periodicals'
end
else
Volume = A['Volume']; -- and does for non-'periodical' cites
end
elseif utilities.in_array (config.CitationClass, cfg.templates_using_volume) then -- render |volume= for cs1 according to the configuration settings
Volume = A['Volume'];
end
extra_text_in_vol_iss_check (Volume, A:ORIGIN ('Volume'), 'v');
local Issue;
if 'citation' == config.CitationClass then
if utilities.is_set (Periodical) and utilities.in_array (Periodical_origin, cfg.citation_issue_t) then -- {{citation}} may render |issue= when these parameters are used
Issue = utilities.hyphen_to_dash (A['Issue']);
end
elseif utilities.in_array (config.CitationClass, cfg.templates_using_issue) then -- conference & map books do not support issue; {{citation}} listed here because included in settings table
if not (utilities.in_array (config.CitationClass, {'conference', 'map', 'citation'}) and not (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical))) then
Issue = utilities.hyphen_to_dash (A['Issue']);
end
end
local ArticleNumber;
if utilities.in_array (config.CitationClass, {'journal', 'conference'}) or ('citation' == config.CitationClass and utilities.is_set (Periodical) and 'journal' == Periodical_origin) then
ArticleNumber = A['ArticleNumber'];
end
extra_text_in_vol_iss_check (Issue, A:ORIGIN ('Issue'), 'i');
local Page;
local Pages;
local At;
local QuotePage;
local QuotePages;
if not utilities.in_array (config.CitationClass, cfg.templates_not_using_page) then -- TODO: rewrite to emit ignored parameter error message?
Page = A['Page'];
Pages = utilities.hyphen_to_dash (A['Pages']);
At = A['At'];
QuotePage = A['QuotePage'];
QuotePages = utilities.hyphen_to_dash (A['QuotePages']);
end
local Edition = A['Edition'];
local PublicationPlace = place_check (A['PublicationPlace'], A:ORIGIN('PublicationPlace'));
local Place = place_check (A['Place'], A:ORIGIN('Place'));
local PublisherName = A['PublisherName'];
local PublisherName_origin = A:ORIGIN('PublisherName');
if utilities.is_set (PublisherName) and (cfg.keywords_xlate['none'] ~= PublisherName) then
local i = 0;
PublisherName, i = utilities.strip_apostrophe_markup (PublisherName); -- strip apostrophe markup so that metadata isn't contaminated; publisher is never italicized
if i and (0 < i) then -- non-zero when markup was stripped so emit an error message
utilities.set_message ('err_apostrophe_markup', {PublisherName_origin});
end
end
if ('document' == config.CitationClass) and not utilities.is_set (PublisherName) then
utilities.set_message ('err_missing_publisher', {config.CitationClass, 'publisher'});
end
local Newsgroup = A['Newsgroup']; -- TODO: strip apostrophe markup?
local Newsgroup_origin = A:ORIGIN('Newsgroup');
if 'newsgroup' == config.CitationClass then
if utilities.is_set (PublisherName) and (cfg.keywords_xlate['none'] ~= PublisherName) then -- general use parameter |publisher= not allowed in cite newsgroup
utilities.set_message ('err_parameter_ignored', {PublisherName_origin});
end
PublisherName = nil; -- ensure that this parameter is unset for the time being; will be used again after COinS
end
local URL = A['URL']; -- TODO: better way to do this for URL, ChapterURL, and MapURL?
local UrlAccess = is_valid_parameter_value (A['UrlAccess'], A:ORIGIN('UrlAccess'), cfg.keywords_lists['url-access'], nil);
if not utilities.is_set (URL) and utilities.is_set (UrlAccess) then
UrlAccess = nil;
utilities.set_message ('err_param_access_requires_param', 'url');
end
local ChapterURL = A['ChapterURL'];
local ChapterUrlAccess = is_valid_parameter_value (A['ChapterUrlAccess'], A:ORIGIN('ChapterUrlAccess'), cfg.keywords_lists['url-access'], nil);
if not utilities.is_set (ChapterURL) and utilities.is_set (ChapterUrlAccess) then
ChapterUrlAccess = nil;
utilities.set_message ('err_param_access_requires_param', {A:ORIGIN('ChapterUrlAccess'):gsub ('%-access', '')});
end
local MapUrlAccess = is_valid_parameter_value (A['MapUrlAccess'], A:ORIGIN('MapUrlAccess'), cfg.keywords_lists['url-access'], nil);
if not utilities.is_set (A['MapURL']) and utilities.is_set (MapUrlAccess) then
MapUrlAccess = nil;
utilities.set_message ('err_param_access_requires_param', {'map-url'});
end
local this_page = mw.title.getCurrentTitle(); -- also used for COinS and for language
local no_tracking_cats = is_valid_parameter_value (A['NoTracking'], A:ORIGIN('NoTracking'), cfg.keywords_lists['yes_true_y'], nil);
-- check this page to see if it is in one of the namespaces that cs1 is not supposed to add to the error categories
if not utilities.is_set (no_tracking_cats) then -- ignore if we are already not going to categorize this page
if cfg.uncategorized_namespaces[this_page.namespace] then -- is this page's namespace id one of the uncategorized namespace ids?
no_tracking_cats = "true"; -- set no_tracking_cats
end
for _, v in ipairs (cfg.uncategorized_subpages) do -- cycle through page name patterns
if this_page.text:match (v) then -- test page name against each pattern
no_tracking_cats = "true"; -- set no_tracking_cats
break; -- bail out if one is found
end
end
end
-- no_tracking_cats = "true"; -- выключаем всю категоризацию для РУВИКИ
-- check for extra |page=, |pages= or |at= parameters. (also sheet and sheets while we're at it)
utilities.select_one (args, {'page', 'p', 'pp', 'pages', 'at', 'sheet', 'sheets'}, 'err_redundant_parameters'); -- this is a dummy call simply to get the error message and category
local coins_pages;
Page, Pages, At, coins_pages = insource_loc_get (Page, A:ORIGIN('Page'), Pages, A:ORIGIN('Pages'), At);
local NoPP = is_valid_parameter_value (A['NoPP'], A:ORIGIN('NoPP'), cfg.keywords_lists['yes_true_y'], nil);
if utilities.is_set (PublicationPlace) and utilities.is_set (Place) then -- both |publication-place= and |place= (|location=) allowed if different
utilities.add_prop_cat ('location-test'); -- add property cat to evaluate how often PublicationPlace and Place are used together
if PublicationPlace == Place then
Place = ''; -- unset; don't need both if they are the same
end
elseif not utilities.is_set (PublicationPlace) and utilities.is_set (Place) then -- when only |place= (|location=) is set ...
PublicationPlace = Place; -- promote |place= (|location=) to |publication-place
end
if PublicationPlace == Place then Place = ''; end -- don't need both if they are the same
local URL_origin = A:ORIGIN('URL'); -- get name of parameter that holds URL
local ChapterURL_origin = A:ORIGIN('ChapterURL'); -- get name of parameter that holds ChapterURL
local ScriptChapter = A['ScriptChapter'];
local ScriptChapter_origin = A:ORIGIN ('ScriptChapter');
local Format = A['Format'];
local ChapterFormat = A['ChapterFormat'];
local TransChapter = A['TransChapter'];
local TransChapter_origin = A:ORIGIN ('TransChapter');
local TransTitle = A['TransTitle'];
local ScriptTitle = A['ScriptTitle'];
--[[
Parameter remapping for cite encyclopedia:
When the citation has these parameters:
|encyclopedia= and |title= then map |title= to |article= and |encyclopedia= to |title= for rendering
|encyclopedia= and |article= then map |encyclopedia= to |title= for rendering
|trans-title= maps to |trans-chapter= when |title= is re-mapped
|url= maps to |chapter-url= when |title= is remapped
All other combinations of |encyclopedia=, |title=, and |article= are not modified
]]
local Encyclopedia = A['Encyclopedia']; -- used as a flag by this module and by ~/COinS
local ScriptEncyclopedia = A['ScriptEncyclopedia'];
local TransEncyclopedia = A['TransEncyclopedia'];
if utilities.is_set (Encyclopedia) or utilities.is_set (ScriptEncyclopedia) then -- emit error message when Encyclopedia set but template is other than {{cite encyclopedia}} or {{citation}}
if 'encyclopaedia' ~= config.CitationClass and 'citation' ~= config.CitationClass then
if utilities.is_set (Encyclopedia) then
utilities.set_message ('err_parameter_ignored', {A:ORIGIN ('Encyclopedia')});
else
utilities.set_message ('err_parameter_ignored', {A:ORIGIN ('ScriptEncyclopedia')});
end
Encyclopedia = nil; -- unset these because not supported by this template
ScriptEncyclopedia = nil;
TransEncyclopedia = nil;
end
elseif utilities.is_set (TransEncyclopedia) then
utilities.set_message ('err_trans_missing_title', {'encyclopedia'});
end
if ('encyclopaedia' == config.CitationClass) or ('citation' == config.CitationClass and utilities.is_set (Encyclopedia)) then
if utilities.is_set (Periodical) and utilities.is_set (Encyclopedia) then -- when both parameters set emit an error message; {{citation}} only; Periodical not allowed in {{cite encyclopedia}}
utilities.set_message ('err_periodical_ignored', {Periodical_origin});
end
if utilities.is_set (Encyclopedia) or utilities.is_set (ScriptEncyclopedia) then
Periodical = Encyclopedia; -- error or no, set Periodical to Encyclopedia for rendering; {{citation}} could (not legitimately) have both; use Encyclopedia
Periodical_origin = A:ORIGIN ('Encyclopedia');
ScriptPeriodical = ScriptEncyclopedia;
ScriptPeriodical_origin = A:ORIGIN ('ScriptEncyclopedia');
if utilities.is_set (Title) or utilities.is_set (ScriptTitle) then
if not utilities.is_set (Chapter) then
Chapter = Title; -- |encyclopedia= and |title= are set so map |title= params to |article= params for rendering
ScriptChapter = ScriptTitle;
ScriptChapter_origin = A:ORIGIN('ScriptTitle')
TransChapter = TransTitle;
ChapterURL = URL;
ChapterURL_origin = URL_origin;
ChapterUrlAccess = UrlAccess;
ChapterFormat = Format;
if not utilities.is_set (ChapterURL) and utilities.is_set (TitleLink) then
Chapter = utilities.make_wikilink (TitleLink, Chapter);
end
Title = Periodical; -- now map |encyclopedia= params to |title= params for rendering
ScriptTitle = ScriptPeriodical or '';
TransTitle = TransEncyclopedia or '';
Periodical = ''; -- redundant so unset
ScriptPeriodical = '';
URL = '';
Format = '';
TitleLink = '';
end
elseif utilities.is_set (Chapter) or utilities.is_set (ScriptChapter) then -- |title= not set
Title = Periodical; -- |encyclopedia= set and |article= set so map |encyclopedia= to |title= for rendering
ScriptTitle = ScriptPeriodical or '';
TransTitle = TransEncyclopedia or '';
Periodical = ''; -- redundant so unset
ScriptPeriodical = '';
end
end
end
-- special case for cite techreport.
local ID = A['ID'];
if (config.CitationClass == "techreport") then -- special case for cite techreport
if utilities.is_set (A['Number']) then -- cite techreport uses 'number', which other citations alias to 'issue'
if not utilities.is_set (ID) then -- can we use ID for the "number"?
ID = A['Number']; -- yes, use it
else -- ID has a value so emit error message
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'id') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'number')});
end
end
end
-- Account for the oddity that is {{cite conference}}, before generation of COinS data.
local ChapterLink -- = A['ChapterLink']; -- deprecated as a parameter but still used internally by cite episode
local Conference = A['Conference'];
local BookTitle = A['BookTitle'];
local TransTitle_origin = A:ORIGIN ('TransTitle');
if 'conference' == config.CitationClass then
if utilities.is_set (BookTitle) then
Chapter = Title;
Chapter_origin = 'title';
-- ChapterLink = TitleLink; -- |chapter-link= is deprecated
ChapterURL = URL;
ChapterUrlAccess = UrlAccess;
ChapterURL_origin = URL_origin;
URL_origin = '';
ChapterFormat = Format;
TransChapter = TransTitle;
TransChapter_origin = TransTitle_origin;
Title = BookTitle;
Format = '';
-- TitleLink = '';
TransTitle = '';
URL = '';
end
elseif 'speech' ~= config.CitationClass then
Conference = ''; -- not cite conference or cite speech so make sure this is empty string
end
-- CS1/2 mode
local Mode;
if cfg.global_cs1_config_t['Mode'] then -- global setting in {{cs1 config}} overrides local |mode= parameter value; nil when empty or assigned value invalid
Mode = is_valid_parameter_value (cfg.global_cs1_config_t['Mode'], 'cs1 config: mode', cfg.keywords_lists['mode'], ''); -- error messaging 'param' here is a hoax
else
Mode = is_valid_parameter_value (A['Mode'], A:ORIGIN('Mode'), cfg.keywords_lists['mode'], '');
end
if cfg.global_cs1_config_t['Mode'] and utilities.is_set (A['Mode']) then -- when template has |mode=<something> which global setting has overridden
utilities.set_message ('maint_overridden_setting'); -- set a maint message
end
-- separator character and postscript
local sepc, PostScript = set_style (Mode:lower(), A['PostScript'], config.CitationClass);
-- controls capitalization of certain static text
local use_lowercase = ( sepc == ',' );
-- cite map oddities
local Cartography = "";
local Scale = "";
local Sheet = A['Sheet'] or '';
local Sheets = A['Sheets'] or '';
if config.CitationClass == "map" then
if utilities.is_set (Chapter) then --TODO: make a function for this and similar?
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'map') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', Chapter_origin)}); -- add error message
end
Chapter = A['Map'];
Chapter_origin = A:ORIGIN('Map');
ChapterURL = A['MapURL'];
ChapterURL_origin = A:ORIGIN('MapURL');
TransChapter = A['TransMap'];
ScriptChapter = A['ScriptMap']
ScriptChapter_origin = A:ORIGIN('ScriptMap')
ChapterUrlAccess = MapUrlAccess;
ChapterFormat = A['MapFormat'];
Cartography = A['Cartography'];
if utilities.is_set ( Cartography ) then
Cartography = sepc .. " " .. wrap_msg ('cartography', Cartography, use_lowercase);
end
Scale = A['Scale'];
if utilities.is_set ( Scale ) then
Scale = sepc .. " " .. Scale;
end
end
-- Account for the oddities that are {{cite episode}} and {{cite serial}}, before generation of COinS data.
local Series = A['Series'];
if 'episode' == config.CitationClass or 'serial' == config.CitationClass then
local SeriesLink = A['SeriesLink'];
SeriesLink = link_title_ok (SeriesLink, A:ORIGIN ('SeriesLink'), Series, 'series'); -- check for wiki-markup in |series-link= or wiki-markup in |series= when |series-link= is set
local Network = A['Network'];
local Station = A['Station'];
local s, n = {}, {};
-- do common parameters first
if utilities.is_set (Network) then table.insert(n, Network); end
if utilities.is_set (Station) then table.insert(n, Station); end
ID = table.concat(n, sepc .. ' ');
if 'episode' == config.CitationClass then -- handle the oddities that are strictly {{cite episode}}
local Season = A['Season'];
local SeriesNumber = A['SeriesNumber'];
if utilities.is_set (Season) and utilities.is_set (SeriesNumber) then -- these are mutually exclusive so if both are set TODO: make a function for this and similar?
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'season') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'seriesno')}); -- add error message
SeriesNumber = ''; -- unset; prefer |season= over |seriesno=
end
-- assemble a table of parts concatenated later into Series
if utilities.is_set (Season) then table.insert(s, wrap_msg ('season', Season, use_lowercase)); end
if utilities.is_set (SeriesNumber) then table.insert(s, wrap_msg ('seriesnum', SeriesNumber, use_lowercase)); end
if utilities.is_set (Issue) then table.insert(s, wrap_msg ('episode', Issue, use_lowercase)); end
Issue = ''; -- unset because this is not a unique parameter
Chapter = Title; -- promote title parameters to chapter
ScriptChapter = ScriptTitle;
ScriptChapter_origin = A:ORIGIN('ScriptTitle');
ChapterLink = TitleLink; -- alias |episode-link=
TransChapter = TransTitle;
ChapterURL = URL;
ChapterUrlAccess = UrlAccess;
ChapterURL_origin = URL_origin;
ChapterFormat = Format;
Title = Series; -- promote series to title
TitleLink = SeriesLink;
Series = table.concat(s, sepc .. ' '); -- this is concatenation of season, seriesno, episode number
if utilities.is_set (ChapterLink) and not utilities.is_set (ChapterURL) then -- link but not URL
Chapter = utilities.make_wikilink (ChapterLink, Chapter);
elseif utilities.is_set (ChapterLink) and utilities.is_set (ChapterURL) then -- if both are set, URL links episode;
Series = utilities.make_wikilink (ChapterLink, Series);
end
URL = ''; -- unset
TransTitle = '';
ScriptTitle = '';
Format = '';
else -- now oddities that are cite serial
Issue = ''; -- unset because this parameter no longer supported by the citation/core version of cite serial
Chapter = A['Episode']; -- TODO: make |episode= available to cite episode someday?
if utilities.is_set (Series) and utilities.is_set (SeriesLink) then
Series = utilities.make_wikilink (SeriesLink, Series);
end
Series = utilities.wrap_style ('italic-title', Series); -- series is italicized
end
end
-- end of {{cite episode}} stuff
-- handle type parameter for those CS1 citations that have default values
local TitleType = A['TitleType'];
local Degree = A['Degree'];
if utilities.in_array (config.CitationClass, {'AV-media-notes', 'document', 'interview', 'mailinglist', 'map', 'podcast', 'pressrelease', 'report', 'speech', 'techreport', 'thesis'}) then
TitleType = set_titletype (config.CitationClass, TitleType);
if utilities.is_set (Degree) and "Thesis" == TitleType then -- special case for cite thesis
TitleType = Degree .. ' ' .. cfg.title_types ['thesis']:lower();
end
end
if utilities.is_set (TitleType) then -- if type parameter is specified
TitleType = utilities.substitute ( cfg.messages['type'], TitleType); -- display it in parentheses
-- TODO: Hack on TitleType to fix bunched parentheses problem
end
-- legacy: promote PublicationDate to Date if neither Date nor Year are set.
local Date = A['Date'];
local Date_origin; -- to hold the name of parameter promoted to Date; required for date error messaging
local PublicationDate = A['PublicationDate'];
local Year = A['Year'];
if not utilities.is_set (Date) then
Date = Year; -- promote Year to Date
Year = nil; -- make nil so Year as empty string isn't used for CITEREF
if not utilities.is_set (Date) and utilities.is_set (PublicationDate) then -- use PublicationDate when |date= and |year= are not set
Date = PublicationDate; -- promote PublicationDate to Date
PublicationDate = ''; -- unset, no longer needed
Date_origin = A:ORIGIN('PublicationDate'); -- save the name of the promoted parameter
else
Date_origin = A:ORIGIN('Year'); -- save the name of the promoted parameter
end
else
Date_origin = A:ORIGIN('Date'); -- not a promotion; name required for error messaging
end
if PublicationDate == Date then PublicationDate = ''; end -- if PublicationDate is same as Date, don't display in rendered citation
--[[
Go test all of the date-holding parameters for valid MOS:DATE format and make sure that dates are real dates. This must be done before we do COinS because here is where
we get the date used in the metadata.
Date validation supporting code is in Module:Citation/CS1/Date_validation
]]
local DF = is_valid_parameter_value (A['DF'], A:ORIGIN('DF'), cfg.keywords_lists['df'], '');
if not utilities.is_set (DF) then
DF = cfg.global_df; -- local |df= if present overrides global df set by {{use xxx date}} template
end
local ArchiveURL;
local ArchiveDate;
local ArchiveFormat = A['ArchiveFormat'];
local archive_url_timestamp; -- timestamp from wayback machine url
ArchiveURL, ArchiveDate, archive_url_timestamp = archive_url_check (A['ArchiveURL'], A['ArchiveDate'])
ArchiveFormat = style_format (ArchiveFormat, ArchiveURL, 'archive-format', 'archive-url');
ArchiveURL, ArchiveDate = is_unique_archive_url (ArchiveURL, URL, ChapterURL, A:ORIGIN('ArchiveURL'), ArchiveDate); -- add error message when URL or ChapterURL == ArchiveURL
local AccessDate = A['AccessDate'];
local COinS_date = {}; -- holds date info extracted from |date= for the COinS metadata by Module:Date verification
local DoiBroken = A['DoiBroken'];
local Embargo = A['Embargo'];
local anchor_year; -- used in the CITEREF identifier
do -- create defined block to contain local variables error_message, date_parameters_list, mismatch
local error_message = '';
-- AirDate has been promoted to Date so not necessary to check it
local date_parameters_list = {
['access-date'] = {val = AccessDate, name = A:ORIGIN ('AccessDate')},
['archive-date'] = {val = ArchiveDate, name = A:ORIGIN ('ArchiveDate')},
['date'] = {val = Date, name = Date_origin},
['doi-broken-date'] = {val = DoiBroken, name = A:ORIGIN ('DoiBroken')},
['pmc-embargo-date'] = {val = Embargo, name = A:ORIGIN ('Embargo')},
['publication-date'] = {val = PublicationDate, name = A:ORIGIN ('PublicationDate')},
['year'] = {val = Year, name = A:ORIGIN ('Year')},
};
local error_list = {};
anchor_year, Embargo = validation.dates(date_parameters_list, COinS_date, error_list);
if utilities.is_set (Year) and utilities.is_set (Date) then -- both |date= and |year= not normally needed;
validation.year_date_check (Year, A:ORIGIN ('Year'), Date, A:ORIGIN ('Date'), error_list);
end
if 0 == #error_list then -- error free dates only; 0 when error_list is empty
local modified = false; -- flag
if utilities.is_set (DF) then -- if we need to reformat dates
modified = validation.reformat_dates (date_parameters_list, DF); -- reformat to DF format, use long month names if appropriate
end
if true == validation.date_hyphen_to_dash (date_parameters_list) then -- convert hyphens to dashes where appropriate
modified = true;
utilities.set_message ('maint_date_format'); -- hyphens were converted so add maint category
end
-- for those wikis that can and want to have English date names translated to the local language; not supported at en.wiki
if cfg.date_name_auto_xlate_enable and validation.date_name_xlate (date_parameters_list, cfg.date_digit_auto_xlate_enable ) then
utilities.set_message ('maint_date_auto_xlated'); -- add maint cat
modified = true;
end
if modified then -- if the date_parameters_list values were modified
AccessDate = date_parameters_list['access-date'].val; -- overwrite date holding parameters with modified values
ArchiveDate = date_parameters_list['archive-date'].val;
Date = date_parameters_list['date'].val;
DoiBroken = date_parameters_list['doi-broken-date'].val;
PublicationDate = date_parameters_list['publication-date'].val;
end
if archive_url_timestamp and utilities.is_set (ArchiveDate) then
validation.archive_date_check (ArchiveDate, archive_url_timestamp, DF); -- does YYYYMMDD in archive_url_timestamp match date in ArchiveDate
end
else
utilities.set_message ('err_bad_date', {utilities.make_sep_list (#error_list, error_list)}); -- add this error message
end
end -- end of do
if utilities.in_array (config.CitationClass, {'book', 'encyclopaedia'}) or -- {{cite book}}, {{cite encyclopedia}}; TODO: {{cite conference}} and others?
('citation' == config.CitationClass and utilities.is_set (Encyclopedia)) or -- {{citation}} as an encylopedia citation
('citation' == config.CitationClass and not utilities.is_set (Periodical)) then -- {{citation}} as a book citation
if utilities.is_set (PublicationPlace) then
if not utilities.is_set (PublisherName) then
local date = COinS_date.rftdate and tonumber (COinS_date.rftdate:match ('%d%d%d%d')); -- get year portion of COinS date (because in Arabic numerals); convert string to number
if date and (1850 <= date) then -- location has no publisher; if date is 1850 or later
utilities.set_message ('maint_location_no_publisher'); -- add maint cat
end
else -- PublisherName has a value
if cfg.keywords_xlate['none'] == PublisherName then -- if that value is 'none' (only for book and encyclopedia citations)
PublisherName = ''; -- unset
end
end
end
end
local ID_list = {}; -- sequence table of rendered identifiers
local ID_list_coins = {}; -- table of identifiers and their values from args; key is same as cfg.id_handlers's key
local Class = A['Class']; -- arxiv class identifier
local ID_support = {
{A['ASINTLD'], 'ASIN', 'err_asintld_missing_asin', A:ORIGIN ('ASINTLD')},
{DoiBroken, 'DOI', 'err_doibroken_missing_doi', A:ORIGIN ('DoiBroken')},
{Embargo, 'PMC', 'err_embargo_missing_pmc', A:ORIGIN ('Embargo')},
}
ID_list, ID_list_coins = identifiers.identifier_lists_get (args, {DoiBroken = DoiBroken, ASINTLD = A['ASINTLD'], Embargo = Embargo, Class = Class}, ID_support);
-- Account for the oddities that are {{cite arxiv}}, {{cite biorxiv}}, {{cite citeseerx}}, {{cite medrxiv}}, {{cite ssrn}}, before generation of COinS data.
if utilities.in_array (config.CitationClass, whitelist.preprint_template_list_t) then -- |arxiv= or |eprint= required for cite arxiv; |biorxiv=, |citeseerx=, |medrxiv=, |ssrn= required for their templates
if not (args[cfg.id_handlers[config.CitationClass:upper()].parameters[1]] or -- can't use ID_list_coins k/v table here because invalid parameters omitted
args[cfg.id_handlers[config.CitationClass:upper()].parameters[2]]) then -- which causes unexpected parameter missing error message
utilities.set_message ('err_' .. config.CitationClass .. '_missing'); -- add error message
end
Periodical = ({['arxiv'] = 'arXiv', ['biorxiv'] = 'bioRxiv', ['citeseerx'] = 'CiteSeerX', ['medrxiv'] = 'medRxiv', ['ssrn'] = 'Social Science Research Network'})[config.CitationClass];
end
-- Link the title of the work if no |url= was provided, but we have a |pmc= or a |doi= with |doi-access=free
if config.CitationClass == "journal" and not utilities.is_set (URL) and not utilities.is_set (TitleLink) and not utilities.in_array (cfg.keywords_xlate[Title], {'off', 'none'}) then -- TODO: remove 'none' once existing citations have been switched to 'off', so 'none' can be used as token for "no title" instead
if 'none' ~= cfg.keywords_xlate[auto_select] then -- if auto-linking not disabled
if identifiers.auto_link_urls[auto_select] then -- manual selection
URL = identifiers.auto_link_urls[auto_select]; -- set URL to be the same as identifier's external link
URL_origin = cfg.id_handlers[auto_select:upper()].parameters[1]; -- set URL_origin to parameter name for use in error message if citation is missing a |title=
elseif identifiers.auto_link_urls['pmc'] then -- auto-select PMC
URL = identifiers.auto_link_urls['pmc']; -- set URL to be the same as the PMC external link if not embargoed
URL_origin = cfg.id_handlers['PMC'].parameters[1]; -- set URL_origin to parameter name for use in error message if citation is missing a |title=
elseif identifiers.auto_link_urls['doi'] then -- auto-select DOI
URL = identifiers.auto_link_urls['doi'];
URL_origin = cfg.id_handlers['DOI'].parameters[1];
end
end
if utilities.is_set (URL) then -- set when using an identifier-created URL
if utilities.is_set (AccessDate) then -- |access-date= requires |url=; identifier-created URL is not |url=
utilities.set_message ('err_accessdate_missing_url'); -- add an error message
AccessDate = ''; -- unset
end
if utilities.is_set (ArchiveURL) then -- |archive-url= requires |url=; identifier-created URL is not |url=
utilities.set_message ('err_archive_missing_url'); -- add an error message
ArchiveURL = ''; -- unset
end
end
end
-- At this point fields may be nil if they weren't specified in the template use. We can use that fact.
-- Test if citation has no title
if not utilities.is_set (Title) and not utilities.is_set (TransTitle) and not utilities.is_set (ScriptTitle) then -- has special case for cite episode
utilities.set_message ('err_citation_missing_title', {'episode' == config.CitationClass and 'series' or 'title'});
end
if utilities.in_array (cfg.keywords_xlate[Title], {'off', 'none'}) and
utilities.in_array (config.CitationClass, {'journal', 'citation'}) and
(utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and
('journal' == Periodical_origin or 'script-journal' == ScriptPeriodical_origin) then -- special case for journal cites
Title = ''; -- set title to empty string
utilities.set_message ('maint_untitled'); -- add maint cat
end
-- COinS metadata (see <http://ocoins.info/>) for automated parsing of citation information.
-- handle the oddity that is cite encyclopedia and {{citation |encyclopedia=something}}. Here we presume that
-- when Periodical, Title, and Chapter are all set, then Periodical is the book (encyclopedia) title, Title
-- is the article title, and Chapter is a section within the article. So, we remap
local coins_chapter = Chapter; -- default assuming that remapping not required
local coins_title = Title; -- et tu
if 'encyclopaedia' == config.CitationClass or ('citation' == config.CitationClass and utilities.is_set (Encyclopedia)) then
if utilities.is_set (Chapter) and utilities.is_set (Title) and utilities.is_set (Periodical) then -- if all are used then
coins_chapter = Title; -- remap
coins_title = Periodical;
end
end
local coins_author = a; -- default for coins rft.au
if 0 < #c then -- but if contributor list
coins_author = c; -- use that instead
end
-- this is the function call to COinS()
local OCinSoutput = metadata.COinS({
['Periodical'] = utilities.strip_apostrophe_markup (Periodical), -- no markup in the metadata
['Encyclopedia'] = Encyclopedia, -- just a flag; content ignored by ~/COinS
['Chapter'] = metadata.make_coins_title (coins_chapter, ScriptChapter), -- Chapter and ScriptChapter stripped of bold / italic / accept-as-written markup
['Degree'] = Degree; -- cite thesis only
['Title'] = metadata.make_coins_title (coins_title, ScriptTitle), -- Title and ScriptTitle stripped of bold / italic / accept-as-written markup
['PublicationPlace'] = PublicationPlace,
['Date'] = COinS_date.rftdate, -- COinS_date.* has correctly formatted date values if Date is valid;
['Season'] = COinS_date.rftssn,
['Quarter'] = COinS_date.rftquarter,
['Chron'] = COinS_date.rftchron,
['Series'] = Series,
['Volume'] = Volume,
['Issue'] = Issue,
['ArticleNumber'] = ArticleNumber,
['Pages'] = coins_pages or metadata.get_coins_pages (first_set ({Sheet, Sheets, Page, Pages, At, QuotePage, QuotePages}, 7)), -- pages stripped of external links
['Edition'] = Edition,
['PublisherName'] = PublisherName or Newsgroup, -- any apostrophe markup already removed from PublisherName
['URL'] = first_set ({ChapterURL, URL}, 2),
['Authors'] = coins_author,
['ID_list'] = ID_list_coins,
['RawPage'] = this_page.prefixedText,
}, config.CitationClass);
-- Account for the oddities that are {{cite arxiv}}, {{cite biorxiv}}, {{cite citeseerx}}, {{cite medrxiv}}, and {{cite ssrn}} AFTER generation of COinS data.
if utilities.in_array (config.CitationClass, whitelist.preprint_template_list_t) then -- we have set rft.jtitle in COinS to arXiv, bioRxiv, CiteSeerX, medRxiv, or ssrn now unset so it isn't displayed
Periodical = ''; -- periodical not allowed in these templates; if article has been published, use cite journal
end
-- special case for cite newsgroup. Do this after COinS because we are modifying Publishername to include some static text
if 'newsgroup' == config.CitationClass and utilities.is_set (Newsgroup) then
PublisherName = utilities.substitute (cfg.messages['newsgroup'], external_link( 'news:' .. Newsgroup, Newsgroup, Newsgroup_origin, nil ));
end
local Editors;
local EditorCount; -- used only for choosing {ed.) or (eds.) annotation at end of editor name-list
local Contributors; -- assembled contributors name list
local contributor_etal;
local Translators; -- assembled translators name list
local translator_etal;
local t = {}; -- translators list from |translator-lastn= / translator-firstn= pairs
t = extract_names (args, 'TranslatorList'); -- fetch translator list from |translatorn= / |translator-lastn=, -firstn=, -linkn=, -maskn=
local Interviewers;
local interviewers_list = {};
interviewers_list = extract_names (args, 'InterviewerList'); -- process preferred interviewers parameters
local interviewer_etal;
-- Now perform various field substitutions.
-- We also add leading spaces and surrounding markup and punctuation to the
-- various parts of the citation, but only when they are non-nil.
do
local last_first_list;
local control = {
format = NameListStyle, -- empty string, '&', 'amp', 'and', or 'vanc'
maximum = nil, -- as if display-authors or display-editors not set
mode = Mode
};
do -- do editor name list first because the now unsupported coauthors used to modify control table
local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayEditors'], A['DisplayEditors'], A:ORIGIN ('DisplayEditors'), #e);
control.maximum, editor_etal = get_display_names (display_names, #e, 'editors', editor_etal, param);
Editors, EditorCount = list_people (control, e, editor_etal);
if 1 == EditorCount and (true == editor_etal or 1 < #e) then -- only one editor displayed but includes etal then
EditorCount = 2; -- spoof to display (eds.) annotation
end
end
do -- now do interviewers
local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayInterviewers'], A['DisplayInterviewers'], A:ORIGIN ('DisplayInterviewers'), #interviewers_list);
control.maximum, interviewer_etal = get_display_names (display_names, #interviewers_list, 'interviewers', interviewer_etal, param);
Interviewers = list_people (control, interviewers_list, interviewer_etal);
end
do -- now do translators
local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayTranslators'], A['DisplayTranslators'], A:ORIGIN ('DisplayTranslators'), #t);
control.maximum, translator_etal = get_display_names (display_names, #t, 'translators', translator_etal, param);
Translators = list_people (control, t, translator_etal);
end
do -- now do contributors
local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayContributors'], A['DisplayContributors'], A:ORIGIN ('DisplayContributors'), #c);
control.maximum, contributor_etal = get_display_names (display_names, #c, 'contributors', contributor_etal, param);
Contributors = list_people (control, c, contributor_etal);
end
do -- now do authors
local display_names, param = display_names_select (cfg.global_cs1_config_t['DisplayAuthors'], A['DisplayAuthors'], A:ORIGIN ('DisplayAuthors'), #a, author_etal);
control.maximum, author_etal = get_display_names (display_names, #a, 'authors', author_etal, param);
last_first_list = list_people (control, a, author_etal);
if utilities.is_set (Authors) then
Authors, author_etal = name_has_etal (Authors, author_etal, false, 'authors'); -- find and remove variations on et al.
if author_etal then
Authors = Authors .. ' ' .. cfg.messages['et al']; -- add et al. to authors parameter
end
else
Authors = last_first_list; -- either an author name list or an empty string
end
end -- end of do
if utilities.is_set (Authors) and utilities.is_set (Collaboration) then
Authors = Authors .. ' (' .. Collaboration .. ')'; -- add collaboration after et al.
end
end
local ConferenceFormat = A['ConferenceFormat'];
local ConferenceURL = A['ConferenceURL'];
ConferenceFormat = style_format (ConferenceFormat, ConferenceURL, 'conference-format', 'conference-url');
Format = style_format (Format, URL, 'format', 'url');
-- special case for chapter format so no error message or cat when chapter not supported
if not (utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'pressrelease', 'podcast', 'newsgroup', 'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn'}) or
('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not utilities.is_set (Encyclopedia))) then
ChapterFormat = style_format (ChapterFormat, ChapterURL, 'chapter-format', 'chapter-url');
end
if not utilities.is_set (URL) then
if utilities.in_array (config.CitationClass, {"web", "podcast", "mailinglist"}) or -- |url= required for cite web, cite podcast, and cite mailinglist
('citation' == config.CitationClass and ('website' == Periodical_origin or 'script-website' == ScriptPeriodical_origin)) then -- and required for {{citation}} with |website= or |script-website=
utilities.set_message ('err_cite_web_url');
end
-- do we have |accessdate= without either |url= or |chapter-url=?
if utilities.is_set (AccessDate) and not utilities.is_set (ChapterURL) then -- ChapterURL may be set when URL is not set;
utilities.set_message ('err_accessdate_missing_url');
AccessDate = '';
end
end
local UrlStatus = is_valid_parameter_value (A['UrlStatus'], A:ORIGIN('UrlStatus'), cfg.keywords_lists['url-status'], '');
local OriginalURL
local OriginalURL_origin
local OriginalFormat
local OriginalAccess;
UrlStatus = UrlStatus:lower(); -- used later when assembling archived text
if utilities.is_set ( ArchiveURL ) then
if utilities.is_set (ChapterURL) then -- if chapter-url= is set apply archive url to it
OriginalURL = ChapterURL; -- save copy of source chapter's url for archive text
OriginalURL_origin = ChapterURL_origin; -- name of |chapter-url= parameter for error messages
OriginalFormat = ChapterFormat; -- and original |chapter-format=
if utilities.in_array (UrlStatus, {'unfit', 'deviated', 'dead', 'usurped', 'bot: unknown'}) then
ChapterURL = ArchiveURL -- swap-in the archive's URL
ChapterURL_origin = A:ORIGIN('ArchiveURL') -- name of |archive-url= parameter for error messages
ChapterFormat = ArchiveFormat or ''; -- swap in archive's format
ChapterUrlAccess = nil; -- restricted access levels do not make sense for archived URLs
end
elseif utilities.is_set (URL) then
OriginalURL = URL; -- save copy of original source URL
OriginalURL_origin = URL_origin; -- name of URL parameter for error messages
OriginalFormat = Format; -- and original |format=
OriginalAccess = UrlAccess;
if utilities.in_array (UrlStatus, {'unfit', 'deviated', 'dead', 'usurped', 'bot: unknown'}) then -- if URL set then |archive-url= applies to it
URL = ArchiveURL -- swap-in the archive's URL
URL_origin = A:ORIGIN('ArchiveURL') -- name of archive URL parameter for error messages
Format = ArchiveFormat or ''; -- swap in archive's format
UrlAccess = nil; -- restricted access levels do not make sense for archived URLs
end
end
elseif utilities.is_set (UrlStatus) then -- if |url-status= is set when |archive-url= is not set
utilities.set_message ('maint_url_status'); -- add maint cat
end
if utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'pressrelease', 'podcast', 'newsgroup', 'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn'}) or -- if any of the 'periodical' cites except encyclopedia
('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not utilities.is_set (Encyclopedia)) then
local chap_param;
if utilities.is_set (Chapter) then -- get a parameter name from one of these chapter related meta-parameters
chap_param = A:ORIGIN ('Chapter')
elseif utilities.is_set (TransChapter) then
chap_param = A:ORIGIN ('TransChapter')
elseif utilities.is_set (ChapterURL) then
chap_param = A:ORIGIN ('ChapterURL')
elseif utilities.is_set (ScriptChapter) then
chap_param = ScriptChapter_origin;
else utilities.is_set (ChapterFormat)
chap_param = A:ORIGIN ('ChapterFormat')
end
if utilities.is_set (chap_param) then -- if we found one
utilities.set_message ('err_chapter_ignored', {chap_param}); -- add error message
Chapter = ''; -- and set them to empty string to be safe with concatenation
TransChapter = '';
ChapterURL = '';
ScriptChapter = '';
ChapterFormat = '';
end
else -- otherwise, format chapter / article title
local no_quotes = false; -- default assume that we will be quoting the chapter parameter value
if utilities.is_set (Contribution) and 0 < #c then -- if this is a contribution with contributor(s)
if utilities.in_array (Contribution:lower(), cfg.keywords_lists.contribution) then -- and a generic contribution title
no_quotes = true; -- then render it unquoted
end
end
Chapter = format_chapter_title (ScriptChapter, ScriptChapter_origin, Chapter, Chapter_origin, TransChapter, TransChapter_origin, ChapterURL, ChapterURL_origin, no_quotes, ChapterUrlAccess); -- Contribution is also in Chapter
if utilities.is_set (Chapter) then
Chapter = Chapter .. ChapterFormat ;
if 'map' == config.CitationClass and utilities.is_set (TitleType) then
Chapter = Chapter .. ' ' .. TitleType; -- map annotation here; not after title
end
Chapter = Chapter .. sepc .. ' ';
elseif utilities.is_set (ChapterFormat) then -- |chapter= not set but |chapter-format= is so ...
Chapter = ChapterFormat .. sepc .. ' '; -- ... ChapterFormat has error message, we want to see it
end
end
-- Format main title
local plain_title = false;
local accept_title;
Title, accept_title = utilities.has_accept_as_written (Title, true); -- remove accept-this-as-written markup when it wraps all of <Title>
if accept_title and ('' == Title) then -- only support forced empty for now "(())"
Title = cfg.messages['notitle']; -- replace by predefined "No title" message
-- TODO: utilities.set_message ( 'err_redundant_parameters', ...); -- issue proper error message instead of muting
ScriptTitle = ''; -- just mute for now
TransTitle = ''; -- just mute for now
plain_title = true; -- suppress text decoration for descriptive title
utilities.set_message ('maint_untitled'); -- add maint cat
end
if not accept_title then -- <Title> not wrapped in accept-as-written markup
if '...' == Title:sub (-3) then -- if ellipsis is the last three characters of |title=
Title = Title:gsub ('(%.%.%.)%.+$', '%1'); -- limit the number of dots to three
elseif not mw.ustring.find (Title, '%.%s*%a%.$') and -- end of title is not a 'dot-(optional space-)letter-dot' initialism ...
not mw.ustring.find (Title, '%s+%a%.$') then -- ...and not a 'space-letter-dot' initial (''Allium canadense'' L.)
Title = mw.ustring.gsub(Title, '%' .. sepc .. '$', ''); -- remove any trailing separator character; sepc and ms.ustring() here for languages that use multibyte separator characters
end
if utilities.is_set (ArchiveURL) and is_archived_copy (Title) then
utilities.set_message ('maint_archived_copy'); -- add maintenance category before we modify the content of Title
end
if is_generic ('generic_titles', Title) then
utilities.set_message ('err_generic_title'); -- set an error message
end
end
if (not plain_title) and (utilities.in_array (config.CitationClass, {'web', 'news', 'journal', 'magazine', 'document', 'pressrelease', 'podcast', 'newsgroup', 'mailinglist', 'interview', 'arxiv', 'biorxiv', 'citeseerx', 'medrxiv', 'ssrn'}) or
('citation' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)) and not utilities.is_set (Encyclopedia)) or
('map' == config.CitationClass and (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical)))) then -- special case for cite map when the map is in a periodical treat as an article
Title = kern_quotes (Title); -- if necessary, separate title's leading and trailing quote marks from module provided quote marks
Title = utilities.wrap_style ('quoted-title', Title);
Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
TransTitle = utilities.wrap_style ('trans-quoted-title', TransTitle );
elseif plain_title or ('report' == config.CitationClass) then -- no styling for cite report and descriptive titles (otherwise same as above)
Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
TransTitle = utilities.wrap_style ('trans-quoted-title', TransTitle ); -- for cite report, use this form for trans-title
else
Title = utilities.wrap_style ('italic-title', Title);
Title = script_concatenate (Title, ScriptTitle, 'script-title'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after title is wrapped
TransTitle = utilities.wrap_style ('trans-italic-title', TransTitle);
end
if utilities.is_set (TransTitle) then
if utilities.is_set (Title) then
TransTitle = " " .. TransTitle;
else
utilities.set_message ('err_trans_missing_title', {'title'});
end
end
if utilities.is_set (Title) then -- TODO: is this the right place to be making Wikisource URLs?
if utilities.is_set (TitleLink) and utilities.is_set (URL) then
utilities.set_message ('err_wikilink_in_url'); -- set an error message because we can't have both
TitleLink = ''; -- unset
end
if not utilities.is_set (TitleLink) and utilities.is_set (URL) then
Title = external_link (URL, Title, URL_origin, UrlAccess) .. TransTitle .. Format;
URL = ''; -- unset these because no longer needed
Format = "";
elseif utilities.is_set (TitleLink) and not utilities.is_set (URL) then
local ws_url;
ws_url = wikisource_url_make (TitleLink); -- ignore ws_label return; not used here
if ws_url then
Title = external_link (ws_url, Title .. ' ', 'ws link in title-link'); -- space char after Title to move icon away from italic text; TODO: a better way to do this?
Title = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], TitleLink, Title});
Title = Title .. TransTitle;
else
Title = utilities.make_wikilink (TitleLink, Title) .. TransTitle;
end
else
local ws_url, ws_label, L; -- Title has italic or quote markup by the time we get here which causes is_wikilink() to return 0 (not a wikilink)
ws_url, ws_label, L = wikisource_url_make (Title:gsub('^[\'"]*(.-)[\'"]*$', '%1')); -- make ws URL from |title= interwiki link (strip italic or quote markup); link portion L becomes tooltip label
if ws_url then
Title = Title:gsub ('%b[]', ws_label); -- replace interwiki link with ws_label to retain markup
Title = external_link (ws_url, Title .. ' ', 'ws link in title'); -- space char after Title to move icon away from italic text; TODO: a better way to do this?
Title = utilities.substitute (cfg.presentation['interwiki-icon'], {cfg.presentation['class-wikisource'], L, Title});
Title = Title .. TransTitle;
else
Title = Title .. TransTitle;
end
end
else
Title = TransTitle;
end
if utilities.is_set (Place) then
Place = " " .. wrap_msg ('written', Place, use_lowercase) .. sepc .. " ";
end
local ConferenceURL_origin = A:ORIGIN('ConferenceURL'); -- get name of parameter that holds ConferenceURL
if utilities.is_set (Conference) then
if utilities.is_set (ConferenceURL) then
Conference = external_link( ConferenceURL, Conference, ConferenceURL_origin, nil );
end
Conference = sepc .. " " .. Conference .. ConferenceFormat;
elseif utilities.is_set (ConferenceURL) then
Conference = sepc .. " " .. external_link( ConferenceURL, nil, ConferenceURL_origin, nil );
end
local Position = '';
if not utilities.is_set (Position) then
local Minutes = A['Minutes'];
local Time = A['Time'];
if utilities.is_set (Minutes) then
if utilities.is_set (Time) then --TODO: make a function for this and similar?
utilities.set_message ('err_redundant_parameters', {utilities.wrap_style ('parameter', 'minutes') .. cfg.presentation['sep_list_pair'] .. utilities.wrap_style ('parameter', 'time')});
end
Position = " " .. Minutes .. " " .. cfg.messages['minutes'];
else
if utilities.is_set (Time) then
local TimeCaption = A['TimeCaption']
if not utilities.is_set (TimeCaption) then
TimeCaption = cfg.messages['event'];
if sepc ~= '.' then
TimeCaption = TimeCaption:lower();
end
end
Position = " " .. TimeCaption .. " " .. Time;
end
end
else
Position = " " .. Position;
At = '';
end
Page, Pages, Sheet, Sheets = format_pages_sheets (Page, Pages, Sheet, Sheets, config.CitationClass, Periodical_origin, sepc, NoPP, use_lowercase);
At = utilities.is_set (At) and (sepc .. " " .. At) or "";
Position = utilities.is_set (Position) and (sepc .. " " .. Position) or "";
if config.CitationClass == 'map' then
local Sections = A['Sections']; -- Section (singular) is an alias of Chapter so set earlier
local Inset = A['Inset'];
if utilities.is_set ( Inset ) then
Inset = sepc .. " " .. wrap_msg ('inset', Inset, use_lowercase);
end
if utilities.is_set ( Sections ) then
Section = sepc .. " " .. wrap_msg ('sections', Sections, use_lowercase);
elseif utilities.is_set ( Section ) then
Section = sepc .. " " .. wrap_msg ('section', Section, use_lowercase);
end
At = At .. Inset .. Section;
end
local Others = A['Others'];
if utilities.is_set (Others) and 0 == #a and 0 == #e then -- add maint cat when |others= has value and used without |author=, |editor=
if config.CitationClass == "AV-media-notes"
or config.CitationClass == "audio-visual" then -- special maint for AV/M which has a lot of 'false' positives right now
utilities.set_message ('maint_others_avm')
else
utilities.set_message ('maint_others');
end
end
Others = utilities.is_set (Others) and (sepc .. " " .. Others) or "";
if utilities.is_set (Translators) then
Others = safe_join ({sepc .. ' ', wrap_msg ('translated', Translators, use_lowercase), Others}, sepc);
end
if utilities.is_set (Interviewers) then
Others = safe_join ({sepc .. ' ', wrap_msg ('interview', Interviewers, use_lowercase), Others}, sepc);
end
local TitleNote = A['TitleNote'];
TitleNote = utilities.is_set (TitleNote) and (sepc .. " " .. TitleNote) or "";
if utilities.is_set (Edition) then
if Edition:match ('%f[%a][Ee]d%n?%.?$') or Edition:match ('%f[%a][Ee]dition$') then -- Ed, ed, Ed., ed., Edn, edn, Edn., edn.
utilities.set_message ('err_extra_text_edition'); -- add error message
end
Edition = " " .. wrap_msg ('edition', Edition);
else
Edition = '';
end
Series = utilities.is_set (Series) and wrap_msg ('series', {sepc, Series}) or ""; -- not the same as SeriesNum
local Agency = A['Agency'] or ''; -- |agency= only supported in {{cite news}}, {{cite press release}}, {{cite web}} and certain {{citation}} templates
if utilities.is_set (Agency) then -- this testing done here because {{citation}} supports 'news' citations
if utilities.in_array (config.CitationClass, {'news', 'pressrelease', 'web'}) or ('citation' == config.CitationClass and utilities.in_array (Periodical_origin, {"newspaper", "work"})) then
Agency = wrap_msg ('agency', {sepc, Agency}); -- format for rendering
else
Agency = ''; -- unset; not supported
utilities.set_message ('err_parameter_ignored', {'agency'}); -- add error message
end
end
Volume = format_volume_issue (Volume, Issue, ArticleNumber, config.CitationClass, Periodical_origin, sepc, use_lowercase);
if utilities.is_set (AccessDate) then
local retrv_text = " " .. cfg.messages['retrieved']
local status, result = pcall(formatDate, AccessDate) -- РУВИКИ: человекочитаемые даты
if status then
AccessDate = string.format("<span class='date'>%s</span>", result)
else
AccessDate = string.format("<span class='error'>(Строка «%s» не является верной датой, пожалуйста, укажите дату в формате <code>ГГГГ-ММ-ДД</code>)</span>", AccessDate)
end
-- AccessDate = nowrap_date (AccessDate); -- wrap in nowrap span if date in appropriate format
if (sepc ~= ".") then retrv_text = retrv_text:lower() end -- if mode is cs2, lower case
AccessDate = utilities.substitute (retrv_text, AccessDate); -- add retrieved text
AccessDate = utilities.substitute (cfg.presentation['accessdate'], {sepc, AccessDate}); -- allow editors to hide accessdates
end
if utilities.is_set (ID) then ID = sepc .. " " .. ID; end
local Docket = A['Docket'];
if "thesis" == config.CitationClass and utilities.is_set (Docket) then
ID = sepc .. " Docket " .. Docket .. ID;
end
if "report" == config.CitationClass and utilities.is_set (Docket) then -- for cite report when |docket= is set
ID = sepc .. ' ' .. Docket; -- overwrite ID even if |id= is set
end
if utilities.is_set (URL) then
URL = " " .. external_link( URL, nil, URL_origin, UrlAccess );
end
local Quote = A['Quote'];
local TransQuote = A['TransQuote'];
local ScriptQuote = A['ScriptQuote'];
if utilities.is_set (Quote) or utilities.is_set (TransQuote) or utilities.is_set (ScriptQuote) then
if utilities.is_set (Quote) then
if Quote:sub(1, 1) == '"' and Quote:sub(-1, -1) == '"' then -- if first and last characters of quote are quote marks
Quote = Quote:sub(2, -2); -- strip them off
end
end
Quote = kern_quotes (Quote); -- kern if needed
Quote = utilities.wrap_style ('quoted-text', Quote ); -- wrap in <q>...</q> tags
if utilities.is_set (ScriptQuote) then
Quote = script_concatenate (Quote, ScriptQuote, 'script-quote'); -- <bdi> tags, lang attribute, categorization, etc.; must be done after quote is wrapped
end
if utilities.is_set (TransQuote) then
if TransQuote:sub(1, 1) == '"' and TransQuote:sub(-1, -1) == '"' then -- if first and last characters of |trans-quote are quote marks
TransQuote = TransQuote:sub(2, -2); -- strip them off
end
Quote = Quote .. " " .. utilities.wrap_style ('trans-quoted-title', TransQuote );
end
if utilities.is_set (QuotePage) or utilities.is_set (QuotePages) then -- add page prefix
local quote_prefix = '';
if utilities.is_set (QuotePage) then
extra_text_in_page_check (QuotePage, 'quote-page'); -- add to maint cat if |quote-page= value begins with what looks like p., pp., etc.
if not NoPP then
quote_prefix = utilities.substitute (cfg.messages['p-prefix'], {sepc, QuotePage}), '', '', '';
else
quote_prefix = utilities.substitute (cfg.messages['nopp'], {sepc, QuotePage}), '', '', '';
end
elseif utilities.is_set (QuotePages) then
extra_text_in_page_check (QuotePages, 'quote-pages'); -- add to maint cat if |quote-pages= value begins with what looks like p., pp., etc.
if tonumber(QuotePages) ~= nil and not NoPP then -- if only digits, assume single page
quote_prefix = utilities.substitute (cfg.messages['p-prefix'], {sepc, QuotePages}), '', '';
elseif not NoPP then
quote_prefix = utilities.substitute (cfg.messages['pp-prefix'], {sepc, QuotePages}), '', '';
else
quote_prefix = utilities.substitute (cfg.messages['nopp'], {sepc, QuotePages}), '', '';
end
end
Quote = quote_prefix .. ": " .. Quote;
else
Quote = sepc .. " " .. Quote;
end
PostScript = ""; -- cs1|2 does not supply terminal punctuation when |quote= is set
end
-- We check length of PostScript here because it will have been nuked by
-- the quote parameters. We'd otherwise emit a message even if there wasn't
-- a displayed postscript.
-- TODO: Should the max size (1) be configurable?
-- TODO: Should we check a specific pattern?
if utilities.is_set(PostScript) and mw.ustring.len(PostScript) > 1 then
utilities.set_message ('maint_postscript')
end
local Archived;
if utilities.is_set (ArchiveURL) then
if not utilities.is_set (ArchiveDate) then -- ArchiveURL set but ArchiveDate not set
utilities.set_message ('err_archive_missing_date'); -- emit an error message
ArchiveURL = ''; -- empty string for concatenation
ArchiveDate = ''; -- empty string for concatenation
end
else
if utilities.is_set (ArchiveDate) then -- ArchiveURL not set but ArchiveDate is set
utilities.set_message ('err_archive_date_missing_url'); -- emit an error message
ArchiveURL = ''; -- empty string for concatenation
ArchiveDate = ''; -- empty string for concatenation
end
end
if utilities.is_set (ArchiveURL) then
local arch_text;
local status, result = pcall(formatDate, ArchiveDate) -- РУВИКИ: человекочитаемые даты
if status then
ArchiveDate = string.format("<span class='date'>%s</span>", result)
else
ArchiveDate = string.format("<span class='error'>(Строка «%s» не является верной датой, пожалуйста, укажите дату в формате <code>ГГГГ-ММ-ДД</code>)</span>", ArchiveDate)
end
if "live" == UrlStatus or "" == UrlStatus then
arch_text = cfg.messages['archived'];
if sepc ~= "." then arch_text = arch_text:lower() end
if utilities.is_set (ArchiveDate) then
Archived = sepc .. ' ' .. utilities.substitute ( cfg.messages['archived-live'],
{external_link( ArchiveURL, arch_text, A:ORIGIN('ArchiveURL'), nil) .. ArchiveFormat, ArchiveDate } );
else
Archived = '';
end
if not utilities.is_set (OriginalURL) then
utilities.set_message ('err_archive_missing_url');
Archived = ''; -- empty string for concatenation
end
elseif utilities.is_set (OriginalURL) then -- UrlStatus is empty, 'dead', 'unfit', 'usurped', 'bot: unknown'
if utilities.in_array (UrlStatus, {'unfit', 'usurped', 'bot: unknown'}) then
arch_text = cfg.messages['archived-unfit'];
if sepc ~= "." then arch_text = arch_text:lower() end
Archived = sepc .. ' ' .. arch_text .. ArchiveDate; -- format already styled
if 'bot: unknown' == UrlStatus then
utilities.set_message ('maint_bot_unknown'); -- and add a category if not already added
else
utilities.set_message ('maint_unfit'); -- and add a category if not already added
end
else -- UrlStatus is empty, 'dead'
arch_text = cfg.messages['archived-dead'];
if sepc ~= "." then arch_text = arch_text:lower() end
if utilities.is_set (ArchiveDate) then
Archived = sepc .. " " .. utilities.substitute ( arch_text,
{ external_link( OriginalURL, cfg.messages['original'], OriginalURL_origin, OriginalAccess ) .. OriginalFormat, ArchiveDate } ); -- format already styled
else
Archived = ''; -- unset for concatenation
end
end
else -- OriginalUrl not set
utilities.set_message ('err_archive_missing_url');
Archived = ''; -- empty string for concatenation
end
elseif utilities.is_set (ArchiveFormat) then
Archived = ArchiveFormat; -- if set and ArchiveURL not set ArchiveFormat has error message
else
Archived = '';
end
local TranscriptURL = A['TranscriptURL']
local TranscriptFormat = A['TranscriptFormat'];
TranscriptFormat = style_format (TranscriptFormat, TranscriptURL, 'transcript-format', 'transcripturl');
local Transcript = A['Transcript'];
local TranscriptURL_origin = A:ORIGIN('TranscriptURL'); -- get name of parameter that holds TranscriptURL
if utilities.is_set (Transcript) then
if utilities.is_set (TranscriptURL) then
Transcript = external_link( TranscriptURL, Transcript, TranscriptURL_origin, nil );
end
Transcript = sepc .. ' ' .. Transcript .. TranscriptFormat;
elseif utilities.is_set (TranscriptURL) then
Transcript = external_link( TranscriptURL, nil, TranscriptURL_origin, nil );
end
local Publisher;
if utilities.is_set (PublicationDate) then
PublicationDate = wrap_msg ('published', PublicationDate);
end
if utilities.is_set (PublisherName) then
if utilities.is_set (PublicationPlace) then
Publisher = sepc .. " " .. PublicationPlace .. ": " .. PublisherName .. PublicationDate;
else
Publisher = sepc .. " " .. PublisherName .. PublicationDate;
end
elseif utilities.is_set (PublicationPlace) then
Publisher= sepc .. " " .. PublicationPlace .. PublicationDate;
else
Publisher = PublicationDate;
end
-- Several of the above rely upon detecting this as nil, so do it last.
if (utilities.is_set (Periodical) or utilities.is_set (ScriptPeriodical) or utilities.is_set (TransPeriodical)) then
if utilities.is_set (Title) or utilities.is_set (TitleNote) then
Periodical = sepc .. " " .. format_periodical (ScriptPeriodical, ScriptPeriodical_origin, Periodical, TransPeriodical, TransPeriodical_origin);
else
Periodical = format_periodical (ScriptPeriodical, ScriptPeriodical_origin, Periodical, TransPeriodical, TransPeriodical_origin);
end
end
local Language = A['Language'];
if utilities.is_set (Language) then
Language = language_parameter (Language); -- format, categories, name from ISO639-1, etc.
else
Language=''; -- language not specified so make sure this is an empty string;
--[[ TODO: need to extract the wrap_msg from language_parameter
so that we can solve parentheses bunching problem with Format/Language/TitleType
]]
end
--[[
Handle the oddity that is cite speech. This code overrides whatever may be the value assigned to TitleNote (through |department=) and forces it to be " (Speech)" so that
the annotation directly follows the |title= parameter value in the citation rather than the |event= parameter value (if provided).
]]
if "speech" == config.CitationClass then -- cite speech only
TitleNote = TitleType; -- move TitleType to TitleNote so that it renders ahead of |event=
TitleType = ''; -- and unset
if utilities.is_set (Periodical) then -- if Periodical, perhaps because of an included |website= or |journal= parameter
if utilities.is_set (Conference) then -- and if |event= is set
Conference = Conference .. sepc .. " "; -- then add appropriate punctuation to the end of the Conference variable before rendering
end
end
end
-- Piece all bits together at last. Here, all should be non-nil.
-- We build things this way because it is more efficient in LUA
-- not to keep reassigning to the same string variable over and over.
local tcommon;
local tcommon2; -- used for book cite when |contributor= is set
if utilities.in_array (config.CitationClass, {"book", "citation"}) and not utilities.is_set (Periodical) then -- special cases for book cites
if utilities.is_set (Contributors) then -- when we are citing foreword, preface, introduction, etc.
tcommon = safe_join ({Title, TitleNote}, sepc); -- author and other stuff will come after this and before tcommon2
tcommon2 = safe_join ({TitleType, Series, Language, Volume, Others, Edition, Publisher}, sepc);
else
tcommon = safe_join ({Title, TitleNote, TitleType, Series, Language, Volume, Others, Edition, Publisher}, sepc);
end
elseif 'map' == config.CitationClass then -- special cases for cite map
if utilities.is_set (Chapter) then -- map in a book; TitleType is part of Chapter
tcommon = safe_join ({Title, Edition, Scale, Series, Language, Cartography, Others, Publisher, Volume}, sepc);
elseif utilities.is_set (Periodical) then -- map in a periodical
tcommon = safe_join ({Title, TitleType, Periodical, Scale, Series, Language, Cartography, Others, Publisher, Volume}, sepc);
else -- a sheet or stand-alone map
tcommon = safe_join ({Title, TitleType, Edition, Scale, Series, Language, Cartography, Others, Publisher}, sepc);
end
elseif 'episode' == config.CitationClass then -- special case for cite episode
tcommon = safe_join ({Title, TitleNote, TitleType, Series, Language, Edition, Publisher}, sepc);
else -- all other CS1 templates
tcommon = safe_join ({Title, TitleNote, Conference, Periodical, TitleType, Series, Language, Volume, Others, Edition, Publisher, Agency}, sepc);
end
if #ID_list > 0 then
ID_list = safe_join( { sepc .. " ", table.concat( ID_list, sepc .. " " ), ID }, sepc );
else
ID_list = ID;
end
local Via = A['Via'];
Via = utilities.is_set (Via) and wrap_msg ('via', Via) or '';
local idcommon;
if 'audio-visual' == config.CitationClass or 'episode' == config.CitationClass then -- special case for cite AV media & cite episode position transcript
idcommon = safe_join( { ID_list, URL, Archived, Transcript, AccessDate, Via, Quote }, sepc );
else
idcommon = safe_join( { ID_list, URL, Archived, AccessDate, Via, Quote }, sepc );
end
local text;
local pgtext = Position .. Sheet .. Sheets .. Page .. Pages .. At;
local OrigDate = A['OrigDate'];
OrigDate = utilities.is_set (OrigDate) and wrap_msg ('origdate', OrigDate) or '';
if utilities.is_set (Date) then
if utilities.is_set (Authors) or utilities.is_set (Editors) then -- date follows authors or editors when authors not set
Date = " (" .. Date .. ")" .. OrigDate .. sepc .. " "; -- in parentheses
else -- neither of authors and editors set
if (string.sub(tcommon, -1, -1) == sepc) then -- if the last character of tcommon is sepc
Date = " " .. Date .. OrigDate; -- Date does not begin with sepc
else
Date = sepc .. " " .. Date .. OrigDate; -- Date begins with sepc
end
end
end
if utilities.is_set (Authors) then
if (not utilities.is_set (Date)) then -- when date is set it's in parentheses; no Authors termination
Authors = terminate_name_list (Authors, sepc); -- when no date, terminate with 0 or 1 sepc and a space
end
if utilities.is_set (Editors) then
local in_text = '';
local post_text = '';
if utilities.is_set (Chapter) and 0 == #c then
in_text = cfg.messages['in'] .. ' ';
if (sepc ~= '.') then
in_text = in_text:lower(); -- lowercase for cs2
end
end
if EditorCount <= 1 then
post_text = ' (' .. cfg.messages['editor'] .. ')'; -- be consistent with no-author, no-date case
else
post_text = ' (' .. cfg.messages['editors'] .. ')';
end
Editors = terminate_name_list (in_text .. Editors .. post_text, sepc); -- terminate with 0 or 1 sepc and a space
end
if utilities.is_set (Contributors) then -- book cite and we're citing the intro, preface, etc.
local by_text = sepc .. ' ' .. cfg.messages['by'] .. ' ';
if (sepc ~= '.') then by_text = by_text:lower() end -- lowercase for cs2
Authors = by_text .. Authors; -- author follows title so tweak it here
if utilities.is_set (Editors) and utilities.is_set (Date) then -- when Editors make sure that Authors gets terminated
Authors = terminate_name_list (Authors, sepc); -- terminate with 0 or 1 sepc and a space
end
if (not utilities.is_set (Date)) then -- when date is set it's in parentheses; no Contributors termination
Contributors = terminate_name_list (Contributors, sepc); -- terminate with 0 or 1 sepc and a space
end
text = safe_join( {Contributors, Date, Chapter, tcommon, Authors, Place, Editors, tcommon2, pgtext, idcommon }, sepc );
else
text = safe_join( {Authors, Date, Chapter, Place, Editors, tcommon, pgtext, idcommon }, sepc );
end
elseif utilities.is_set (Editors) then
if utilities.is_set (Date) then
if EditorCount <= 1 then
Editors = Editors .. cfg.presentation['sep_name'] .. cfg.messages['editor'];
else
Editors = Editors .. cfg.presentation['sep_name'] .. cfg.messages['editors'];
end
else
if EditorCount <= 1 then
Editors = Editors .. " (" .. cfg.messages['editor'] .. ")" .. sepc .. " "
else
Editors = Editors .. " (" .. cfg.messages['editors'] .. ")" .. sepc .. " "
end
end
text = safe_join( {Editors, Date, Chapter, Place, tcommon, pgtext, idcommon}, sepc );
else
if utilities.in_array (config.CitationClass, {"journal", "citation"}) and utilities.is_set (Periodical) then
text = safe_join( {Chapter, Place, tcommon, pgtext, Date, idcommon}, sepc );
else
text = safe_join( {Chapter, Place, tcommon, Date, pgtext, idcommon}, sepc );
end
end
if utilities.is_set (PostScript) and PostScript ~= sepc then
text = safe_join( {text, sepc}, sepc ); -- Deals with italics, spaces, etc.
if '.' == sepc then -- remove final seperator if present
text = text:gsub ('%' .. sepc .. '$', ''); -- dot must be escaped here
else
text = mw.ustring.gsub (text, sepc .. '$', ''); -- using ustring for non-dot sepc (likely a non-Latin character)
end
end
text = safe_join( {text, PostScript}, sepc );
-- Now enclose the whole thing in a <cite> element
local options_t = {};
options_t.class = cite_class_attribute_make (config.CitationClass, Mode);
local Ref = is_valid_parameter_value (A['Ref'], A:ORIGIN('Ref'), cfg.keywords_lists['ref'], nil, true); -- nil when |ref=harv; A['Ref'] else
-- Если указан параметр ref, то формируем ref-якорь по логике из рувики
-- Если параметр не указан или ref=harv, то формируем якорь по енвики
-- После зачистки всех ref=harv (~350), можно будет убрать код внутри utilities.is_set(Ref)
if 'none' ~= cfg.keywords_xlate[(Ref and Ref:lower()) or ''] then
local citeref_id = Ref
local year = first_set ({Year, anchor_year}, 2); -- Year first for legacy citations and for YMD dates that require disambiguation
if not utilities.is_set(Ref) then
local namelist_t = {}; -- holds selected contributor, author, editor name list
if #c > 0 then -- if there is a contributor list
namelist_t = c; -- select it
elseif #a > 0 then -- or an author list
namelist_t = a;
elseif #e > 0 then -- or an editor list
namelist_t = e;
end
if #namelist_t > 0 then -- if there are names in namelist_t
citeref_id = make_citeref_id (namelist_t, year); -- go make the CITEREF anchor
if mw.uri.anchorEncode (citeref_id) == ((Ref and mw.uri.anchorEncode (Ref)) or '') then -- Ref may already be encoded (by {{sfnref}}) so citeref_id must be encoded before comparison
utilities.set_message ('maint_ref_duplicates_default');
end
else
citeref_id = ''; -- unset
end
elseif mw.ustring.sub(Ref, 0, 7) ~= 'CITEREF' then -- для рувики: иная генерация ref-якорей
if mw.ustring.match(citeref_id, '%d%d%d%d') then
citeref_id = 'CITEREF' .. citeref_id
else
local yearForRef = nil
if year and mw.ustring.match(year, '^%d%d%d%d$') then
yearForRef = mw.ustring.match(year, '^%d%d%d%d$')
elseif Date and mw.ustring.match(Date, '%d%d%d%d') then
yearForRef = mw.ustring.match(Date, '%d%d%d%d')
end
if yearForRef then
citeref_id = 'CITEREF' .. citeref_id .. yearForRef
else
citeref_id = '' -- TODO: для рувики: выдавать ошибку?
end
end
end
options_t.id = citeref_id or '';
end
if string.len (text:gsub('%b<>', '')) <= 2 then -- remove html and html-like tags; then get length of what remains;
z.error_cats_t = {}; -- blank the categories list
z.error_msgs_t = {}; -- blank the error messages list
OCinSoutput = nil; -- blank the metadata string
text = ''; -- blank the the citation
utilities.set_message ('err_empty_citation'); -- set empty citation message and category
end
local render_t = {}; -- here we collect the final bits for concatenation into the rendered citation
if utilities.is_set (options_t.id) then -- here we wrap the rendered citation in <cite ...>...</cite> tags
table.insert (render_t, utilities.substitute (cfg.presentation['cite-id'], {mw.uri.anchorEncode(options_t.id), mw.text.nowiki(options_t.class), text})); -- when |ref= is set or when there is a namelist
else
table.insert (render_t, utilities.substitute (cfg.presentation['cite'], {mw.text.nowiki(options_t.class), text})); -- when |ref=none or when namelist_t empty and |ref= is missing or is empty
end
if OCinSoutput then -- blanked when citation is 'empty' so don't bother to add boilerplate metadata span
table.insert (render_t, utilities.substitute (cfg.presentation['ocins'], OCinSoutput)); -- format and append metadata to the citation
end
local template_name = ('citation' == config.CitationClass) and 'citation' or 'cite ' .. (cfg.citation_class_map_t[config.CitationClass] or config.CitationClass);
local template_link = '[[Template:' .. template_name .. '|' .. template_name .. ']]';
local msg_prefix = '<code class="cs1-code">{{' .. template_link .. '}}</code>: ';
if 0 ~= #z.error_msgs_t then
mw.addWarning (utilities.substitute (cfg.messages.warning_msg_e, template_link));
table.insert (render_t, ' '); -- insert a space between citation and its error messages
table.sort (z.error_msgs_t); -- sort the error messages list; sorting includes wrapping <span> and <code> tags; hidden-error sorts ahead of visible-error
local hidden = true; -- presume that the only error messages emited by this template are hidden
for _, v in ipairs (z.error_msgs_t) do -- spin through the list of error messages
if v:find ('cs1-visible-error', 1, true) then -- look for the visible error class name
hidden = false; -- found one; so don't hide the error message prefix
break; -- and done because no need to look further
end
end
z.error_msgs_t[1] = table.concat ({utilities.error_comment (msg_prefix, hidden), z.error_msgs_t[1]}); -- add error message prefix to first error message to prevent extraneous punctuation
table.insert (render_t, table.concat (z.error_msgs_t, '; ')); -- make a big string of error messages and add it to the rendering
end
if 0 ~= #z.maint_cats_t then
mw.addWarning (utilities.substitute (cfg.messages.warning_msg_m, template_link));
table.sort (z.maint_cats_t); -- sort the maintenance messages list
local maint_msgs_t = {}; -- here we collect all of the maint messages
if 0 == #z.error_msgs_t then -- if no error messages
table.insert (maint_msgs_t, msg_prefix); -- insert message prefix in maint message livery
end
for _, v in ipairs( z.maint_cats_t ) do -- append maintenance categories
table.insert (maint_msgs_t, -- assemble new maint message and add it to the maint_msgs_t table
table.concat ({v, ' (', utilities.substitute (cfg.messages[':cat wikilink'], v), ')'})
);
end
table.insert (render_t, utilities.substitute (cfg.presentation['hidden-maint'], table.concat (maint_msgs_t, ' '))); -- wrap the group of maint messages with proper presentation and save
end
if not no_tracking_cats then
local sort_key;
local cat_wikilink = 'cat wikilink';
if cfg.enable_sort_keys then -- when namespace sort keys enabled
local namespace_number = mw.title.getCurrentTitle().namespace; -- get namespace number for this wikitext
sort_key = (0 ~= namespace_number and (cfg.name_space_sort_keys[namespace_number] or cfg.name_space_sort_keys.other)) or nil; -- get sort key character; nil for mainspace
cat_wikilink = (not sort_key and 'cat wikilink') or 'cat wikilink sk'; -- make <cfg.messages> key
end
for _, v in ipairs (z.error_cats_t) do -- append error categories
table.insert (render_t, utilities.substitute (cfg.messages[cat_wikilink], {v, sort_key}));
end
for _, v in ipairs (z.maint_cats_t) do -- append maintenance categories
table.insert (render_t, utilities.substitute (cfg.messages[cat_wikilink], {v, sort_key}));
end
-- for _, v in ipairs (z.prop_cats_t) do -- append properties categories
-- table.insert (render_t, utilities.substitute (cfg.messages['cat wikilink'], v)); -- no sort keys
-- end
end
return table.concat (render_t); -- make a big string and done
end
--[[--------------------------< V A L I D A T E >--------------------------------------------------------------
Looks for a parameter's name in one of several whitelists.
Parameters in the whitelist can have three values:
true - active, supported parameters
false - deprecated, supported parameters
nil - unsupported parameters
]]
local function validate (name, cite_class, empty)
local name = tostring (name);
local enum_name; -- parameter name with enumerator (if any) replaced with '#'
local state;
local function state_test (state, name) -- local function to do testing of state values
if true == state then return true; end -- valid actively supported parameter
if false == state then
if empty then return nil; end -- empty deprecated parameters are treated as unknowns
deprecated_parameter (name); -- parameter is deprecated but still supported
return true;
end
if 'tracked' == state then
local base_name = name:gsub ('%d', ''); -- strip enumerators from parameter names that have them to get the base name
utilities.add_prop_cat ('tracked-param', {base_name}, base_name); -- add a properties category; <base_name> modifies <key>
return true;
end
return nil;
end
if name:find ('#') then -- # is a cs1|2 reserved character so parameters with # not permitted
return nil;
end
-- replace enumerator digit(s) with # (|last25= becomes |last#=) (mw.ustring because non-Western 'local' digits)
enum_name = mw.ustring.gsub (name, '%d+$', '#'); -- where enumerator is last charaters in parameter name (these to protect |s2cid=)
enum_name = mw.ustring.gsub (enum_name, '%d+([%-l])', '#%1'); -- where enumerator is in the middle of the parameter name; |author#link= is the oddity
if 'document' == cite_class then -- special case for {{cite document}}
state = whitelist.document_parameters_t[enum_name]; -- this list holds enumerated and nonenumerated parameters
if true == state_test (state, name) then return true; end
return false;
end
if utilities.in_array (cite_class, whitelist.preprint_template_list_t) then -- limited parameter sets allowed for these templates
state = whitelist.limited_parameters_t[enum_name]; -- this list holds enumerated and nonenumerated parameters
if true == state_test (state, name) then return true; end
state = whitelist.preprint_arguments_t[cite_class][name]; -- look in the parameter-list for the template identified by cite_class
if true == state_test (state, name) then return true; end
return false; -- not supported because not found or name is set to nil
end -- end limited parameter-set templates
if utilities.in_array (cite_class, whitelist.unique_param_template_list_t) then -- template-specific parameters for templates that accept parameters from the basic argument list
state = whitelist.unique_arguments_t[cite_class][name]; -- look in the template-specific parameter-lists for the template identified by cite_class
if true == state_test (state, name) then return true; end
end -- if here, fall into general validation
state = whitelist.common_parameters_t[enum_name]; -- all other templates; all normal parameters allowed; this list holds enumerated and nonenumerated parameters
if true == state_test (state, name) then return true; end
return false; -- not supported because not found or name is set to nil
end
--[=[-------------------------< I N T E R _ W I K I _ C H E C K >----------------------------------------------
check <value> for inter-language interwiki-link markup. <prefix> must be a MediaWiki-recognized language
code. when these values have the form (without leading colon):
[[<prefix>:link|label]] return label as plain-text
[[<prefix>:link]] return <prefix>:link as plain-text
return value as is else
]=]
local function inter_wiki_check (parameter, value)
local prefix = value:match ('%[%[(%a+):'); -- get an interwiki prefix if one exists
local _;
if prefix and cfg.inter_wiki_map[prefix:lower()] then -- if prefix is in the map, needs preceding colon so
utilities.set_message ('err_bad_paramlink', parameter); -- emit an error message
_, value, _ = utilities.is_wikilink (value); -- extract label portion from wikilink
end
return value;
end
--[[--------------------------< M I S S I N G _ P I P E _ C H E C K >------------------------------------------
Look at the contents of a parameter. If the content has a string of characters and digits followed by an equal
sign, compare the alphanumeric string to the list of cs1|2 parameters. If found, then the string is possibly a
parameter that is missing its pipe. There are two tests made:
{{cite ... |title=Title access-date=2016-03-17}} -- the first parameter has a value and whitespace separates that value from the missing pipe parameter name
{{cite ... |title=access-date=2016-03-17}} -- the first parameter has no value (whitespace after the first = is trimmed by MediaWiki)
cs1|2 shares some parameter names with XML/HTML attributes: class=, title=, etc. To prevent false positives XML/HTML
tags are removed before the search.
If a missing pipe is detected, this function adds the missing pipe maintenance category.
]]
local function missing_pipe_check (parameter, value)
local capture;
value = value:gsub ('%b<>', ''); -- remove XML/HTML tags because attributes: class=, title=, etc.
capture = value:match ('%s+(%a[%w%-]+)%s*=') or value:match ('^(%a[%w%-]+)%s*='); -- find and categorize parameters with possible missing pipes
if capture and validate (capture) then -- if the capture is a valid parameter name
utilities.set_message ('err_missing_pipe', parameter);
end
end
--[[--------------------------< H A S _ E X T R A N E O U S _ P U N C T >--------------------------------------
look for extraneous terminal punctuation in most parameter values; parameters listed in skip table are not checked
]]
local function has_extraneous_punc (param, value)
if 'number' == type (param) then
return;
end
param = param:gsub ('%d+', '#'); -- enumerated name-list mask params allow terminal punct; normalize
if cfg.punct_skip[param] then
return; -- parameter name found in the skip table so done
end
if value:match ('[,;:]$') then
utilities.set_message ('maint_extra_punct'); -- has extraneous punctuation; add maint cat
end
if value:match ('^=') then -- sometimes an extraneous '=' character appears ...
utilities.set_message ('maint_extra_punct'); -- has extraneous punctuation; add maint cat
end
end
--[[--------------------------< H A S _ E X T R A N E O U S _ U R L >------------------------------------------
look for extraneous url parameter values; parameters listed in skip table are not checked
]]
local function has_extraneous_url (url_param_t)
local url_error_t = {};
check_for_url (url_param_t, url_error_t); -- extraneous url check
if 0 ~= #url_error_t then -- non-zero when there are errors
table.sort (url_error_t);
utilities.set_message ('err_param_has_ext_link', {utilities.make_sep_list (#url_error_t, url_error_t)}); -- add this error message
end
end
--[[--------------------------< C I T A T I O N >--------------------------------------------------------------
This is used by templates such as {{cite book}} to create the actual citation text.
]]
local function citation(frame)
Frame = frame; -- save a copy in case we need to display an error message in preview mode
local config = {}; -- table to store parameters from the module {{#invoke:}}
for k, v in pairs( frame.args ) do -- get parameters from the {{#invoke}} frame
config[k] = v;
-- args[k] = v; -- crude debug support that allows us to render a citation from module {{#invoke:}}; skips parameter validation; TODO: keep?
end
-- i18n: set the name that your wiki uses to identify sandbox subpages from sandbox template invoke (or can be set here)
local sandbox = ((config.SandboxPath and '' ~= config.SandboxPath) and config.SandboxPath) or '/sandbox'; -- sandbox path from {{#invoke:Citation/CS1/sandbox|citation|SandboxPath=/...}}
is_sandbox = nil ~= string.find (frame:getTitle(), sandbox, 1, true); -- is this invoke the sandbox module?
sandbox = is_sandbox and sandbox or ''; -- use i18n sandbox to load sandbox modules when this module is the sandox; live modules else
local pframe = frame:getParent()
local styles;
cfg = mw.loadData ('Module:Citation/CS1/Configuration' .. sandbox); -- load sandbox versions of support modules when {{#invoke:Citation/CS1/sandbox|...}}; live modules else
whitelist = mw.loadData ('Module:Citation/CS1/Whitelist' .. sandbox);
utilities = require ('Module:Citation/CS1/Utilities' .. sandbox);
validation = require ('Module:Citation/CS1/Date_validation' .. sandbox);
identifiers = require ('Module:Citation/CS1/Identifiers' .. sandbox);
metadata = require ('Module:Citation/CS1/COinS' .. sandbox);
styles = 'Module:Citation/CS1' .. sandbox .. '/styles.css';
utilities.set_selected_modules (cfg); -- so that functions in Utilities can see the selected cfg tables
identifiers.set_selected_modules (cfg, utilities); -- so that functions in Identifiers can see the selected cfg tables and selected Utilities module
validation.set_selected_modules (cfg, utilities); -- so that functions in Date validataion can see selected cfg tables and the selected Utilities module
metadata.set_selected_modules (cfg, utilities); -- so that functions in COinS can see the selected cfg tables and selected Utilities module
z = utilities.z; -- table of error and category tables in Module:Citation/CS1/Utilities
is_preview_mode = not utilities.is_set (frame:preprocess ('{{REVISIONID}}'));
local args = {}; -- table where we store all of the template's arguments
local suggestions = {}; -- table where we store suggestions if we need to loadData them
local error_text; -- used as a flag
local capture; -- the single supported capture when matching unknown parameters using patterns
local empty_unknowns = {}; -- sequence table to hold empty unknown params for error message listing
for k, v in pairs( pframe.args ) do -- get parameters from the parent (template) frame
v = mw.ustring.gsub (v, '^%s*(.-)%s*$', '%1'); -- trim leading/trailing whitespace; when v is only whitespace, becomes empty string
if v ~= '' then
if ('string' == type (k)) then
k = mw.ustring.gsub (k, '%d', cfg.date_names.local_digits); -- for enumerated parameters, translate 'local' digits to Western 0-9
end
if not validate( k, config.CitationClass ) then
if type (k) ~= 'string' then -- exclude empty numbered parameters
if v:match("%S+") ~= nil then
error_text = utilities.set_message ('err_text_ignored', {v});
end
elseif validate (k:lower(), config.CitationClass) then
error_text = utilities.set_message ('err_parameter_ignored_suggest', {k, k:lower()}); -- suggest the lowercase version of the parameter
else
if nil == suggestions.suggestions then -- if this table is nil then we need to load it
suggestions = mw.loadData ('Module:Citation/CS1/Suggestions' .. sandbox); --load sandbox version of suggestion module when {{#invoke:Citation/CS1/sandbox|...}}; live module else
end
for pattern, param in pairs (suggestions.patterns) do -- loop through the patterns to see if we can suggest a proper parameter
capture = k:match (pattern); -- the whole match if no capture in pattern else the capture if a match
if capture then -- if the pattern matches
param = utilities.substitute (param, capture); -- add the capture to the suggested parameter (typically the enumerator)
if validate (param, config.CitationClass) then -- validate the suggestion to make sure that the suggestion is supported by this template (necessary for limited parameter lists)
error_text = utilities.set_message ('err_parameter_ignored_suggest', {k, param}); -- set the suggestion error message
else
error_text = utilities.set_message ('err_parameter_ignored', {k}); -- suggested param not supported by this template
v = ''; -- unset
end
end
end
if not utilities.is_set (error_text) then -- couldn't match with a pattern, is there an explicit suggestion?
if (suggestions.suggestions[ k:lower() ] ~= nil) and validate (suggestions.suggestions[ k:lower() ], config.CitationClass) then
utilities.set_message ('err_parameter_ignored_suggest', {k, suggestions.suggestions[ k:lower() ]});
else
utilities.set_message ('err_parameter_ignored', {k});
v = ''; -- unset value assigned to unrecognized parameters (this for the limited parameter lists)
end
end
end
end
args[k] = v; -- save this parameter and its value
elseif not utilities.is_set (v) then -- for empty parameters
if not validate (k, config.CitationClass, true) then -- is this empty parameter a valid parameter
k = ('' == k) and '(empty string)' or k; -- when k is empty string (or was space(s) trimmed to empty string), replace with descriptive text
table.insert (empty_unknowns, utilities.wrap_style ('parameter', k)); -- format for error message and add to the list
end
-- crude debug support that allows us to render a citation from module {{#invoke:}} TODO: keep?
-- elseif args[k] ~= nil or (k == 'postscript') then -- when args[k] has a value from {{#invoke}} frame (we don't normally do that)
-- args[k] = v; -- overwrite args[k] with empty string from pframe.args[k] (template frame); v is empty string here
end -- not sure about the postscript bit; that gets handled in parameter validation; historical artifact?
end
if 0 ~= #empty_unknowns then -- create empty unknown error message
utilities.set_message ('err_param_unknown_empty', {
1 == #empty_unknowns and '' or 's',
utilities.make_sep_list (#empty_unknowns, empty_unknowns)
});
end
local url_param_t = {};
for k, v in pairs( args ) do
if 'string' == type (k) then -- don't evaluate positional parameters
has_invisible_chars (k, v); -- look for invisible characters
end
has_extraneous_punc (k, v); -- look for extraneous terminal punctuation in parameter values
missing_pipe_check (k, v); -- do we think that there is a parameter that is missing a pipe?
args[k] = inter_wiki_check (k, v); -- when language interwiki-linked parameter missing leading colon replace with wiki-link label
if 'string' == type (k) and not cfg.url_skip[k] then -- when parameter k is not positional and not in url skip table
url_param_t[k] = v; -- make a parameter/value list for extraneous url check
end
end
has_extraneous_url (url_param_t); -- look for url in parameter values where a url does not belong
return table.concat ({
frame:extensionTag ('templatestyles', '', {src=styles}),
citation0( config, args)
});
end
--[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------
]]
return {citation = citation};
79118ee25d3a893b095e8a280156cc50dc140901
Модуль:Hatnote
828
79
131
130
2024-08-09T16:56:43Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
local get_args = require('Module:Arguments').getArgs
local mError
local yesno = function (v) return require('Module:Yesno')(v, true) end
local p, tr = {}, {}
local current_title = mw.title.getCurrentTitle()
local tracking_categories = {
no_prefix = 'Википедия:Страницы с модулем Hatnote без указания префикса',
no_links = 'Википедия:Страницы с модулем Hatnote без ссылок',
red_link = 'Википедия:Страницы с модулем Hatnote с красной ссылкой',
bad_format = 'Википедия:Страницы с модулем Hatnote с некорректно заполненными параметрами',
unparsable_link = 'Википедия:Страницы с модулем Hatnote с нечитаемой ссылкой',
formatted = 'Википедия:Страницы с модулем Hatnote с готовым форматированием',
}
local function index(t1, t2)
return setmetatable(t1, {__index = t2})
end
local function concat(e1, e2)
return tostring(e1) .. tostring(e2)
end
function tr.define_categories(tracked_cases)
local categories = setmetatable({}, {
__tostring = function (self) return table.concat(self) end,
__concat = concat
})
function categories:add(element, nocat)
if not nocat then
local cat_name
if tracked_cases and tracked_cases[element] then
cat_name = tracked_cases[element]
else
cat_name = element
end
table.insert(self, string.format('[[Категория:%s]]', cat_name))
end
end
return categories
end
function tr.error(msg, categories, preview_only)
local current_frame = mw.getCurrentFrame()
local parent_frame = current_frame:getParent()
local res_frame_title = parent_frame and parent_frame:getTitle() ~= current_title.prefixedText and
parent_frame:getTitle() or
current_frame:getTitle()
if not preview_only or current_frame:preprocess('{{REVISIONID}}') == '' then
mError = require('Module:Error')
return mError.error{
tag = 'div',
string.format('Ошибка в [[%s]]: %s.'
.. (preview_only and '<br><small>Это сообщение показывается только во время предпросмотра.</small>' or ''), res_frame_title, msg)
} .. categories
else
return categories
end
end
function p.parse_link(frame)
local args = get_args(frame)
local link = args[1]:gsub('\n', '')
local label
link = mw.text.trim(link:match('^%[%[([^%]]+)%]%]$') or link)
if link:sub(1, 1) == '/' then
label = link
link = current_title.prefixedText .. link
end
link = link:match(':?(.+)')
if link:match('|') then
link, label = link:match('^([^%|]+)%|(.+)$')
end
if not mw.title.new(link) then
return nil, nil
end
return link, label
end
function p.format_link(frame)
-- {{ссылка на раздел}}
local args = get_args(frame)
local link, section, label = args[1], args[2], args[3]
if not link then
link = current_title.prefixedText
if section then
link = '#' .. section
label = label or '§ ' .. section
end
else
local parsed_link, parsed_label = p.parse_link{link}
if parsed_link then
link = parsed_link
else
return link
end
if section and not link:match('#') then
link = link .. '#' .. section
if parsed_label then
parsed_label = parsed_label .. '#' .. section
end
end
label = (label or parsed_label or link):gsub('^([^#]-)#(.+)$', '%1 § %2')
end
if label and label ~= link then
return string.format('[[:%s|%s]]', link, label)
else
return string.format('[[:%s]]', link)
end
end
function p.remove_precision(frame)
-- {{без уточнения}}
local args = get_args(frame)
local title = args[1]
return title:match('^(.+)%s+%b()$') or title
end
function p.is_disambig(frame)
local args = get_args(frame)
local title = args[1]
local page = mw.title.new(title)
if not page or not page.exists or mw.title.equals(page, current_title) then
return false
end
local page_content = page:getContent()
local mw_list_content = mw.title.new('MediaWiki:Disambiguationspage'):getContent()
local lang = mw.language.getContentLanguage()
for template in mw.ustring.gmatch(mw_list_content, '%*%s?%[%[Шаблон:([^%]]+)') do
if page_content:match('{{' .. template) or page_content:match('{{' .. lang:lcfirst(template)) then
return true
end
end
return false
end
function p.list(frame)
local args = get_args(frame, {trim = false})
local list_sep = args.list_sep or args['разделитель списка'] or ', '
local last_list_sep = yesno(args.natural_join) ~= false and ' и ' or list_sep
local links_ns = args.links_ns or args['ПИ ссылок']
local bold_links = yesno(args.bold_links or args['ссылки болдом'])
local res_list = {}
local tracked = {
red_link = false,
bad_format = false,
formatted = false,
unparsable_link = false
}
local i = 1
while args[i] do
local link = args[i]
local label = args['l' .. i]
local element = ''
if link:match('<span') then -- TODO: переписать
tracked.formatted = true
element = link -- for {{не переведено}}
else
local bad_format = (link:match('|') or link:match('[%[%]]')) ~= nil
local parsed_link, parsed_label = p.parse_link{link}
if parsed_link then
tracked.bad_format = tracked.bad_format or bad_format
if links_ns then
parsed_label = parsed_label or parsed_link
parsed_link = mw.site.namespaces[links_ns].name .. ':' .. parsed_link
end
local title = mw.title.new(parsed_link)
tracked.red_link = tracked.red_link or not (title.isExternal or title.exists)
element = p.format_link{parsed_link, nil, label or parsed_label}
else
tracked.unparsable_link = true
element = link
end
end
if bold_links then
element = string.format('<b>%s</b>', element)
end
table.insert(res_list, element)
i = i + 1
end
return setmetatable(res_list, {
__index = tracked,
__tostring = function (self) return mw.text.listToText(self, list_sep, last_list_sep) end,
__concat = concat,
__pairs = function (self) return pairs(tracked) end
})
end
function p.hatnote(frame)
local args = get_args(frame)
local text = args[1]
local id = args.id
local extraclasses = args.extraclasses
local hide_disambig = yesno(args.hide_disambig)
local res = mw.html.create('div')
:attr('id', id)
:addClass('hatnote')
:addClass('navigation-not-searchable')
:addClass(extraclasses)
:wikitext(text)
if hide_disambig then
res:addClass('dabhide')
end
return res
end
function p.main(frame, _tracking_categories)
local args = get_args(frame, {trim = false})
local prefix = args.prefix or args['префикс']
local prefix_plural = args.prefix_plural or args['префикс мн. ч.']
local sep = args.sep or args['разделитель'] or ' '
local dot = yesno(args.dot or args['точка']) and '.' or ''
local nocat = yesno(args.nocat)
local preview_error = yesno(args.preview_error)
local empty_list_message = args.empty_list_message or 'Не указано ни одной страницы'
categories = tr.define_categories(index(_tracking_categories or {}, tracking_categories))
if not prefix then
categories:add('no_prefix', nocat)
return tr.error('Не указан префикс', categories)
end
if not args[1] then
categories:add('no_links', nocat)
return tr.error(empty_list_message, categories, preview_error)
end
if args[2] and prefix_plural then
prefix = prefix_plural
end
local list = p.list(args)
for k, v in pairs(list) do
if type(v) == 'boolean' and v then
categories:add(k, nocat)
end
end
return p.hatnote(index({prefix .. sep .. list .. dot}, args)) .. categories
end
return index(p, tr)
315cdda5f53c2b0188793a6cc6c40f7f371361e0
Модуль:Unsubst
828
80
133
132
2024-08-09T16:58:24Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
local checkType = require('libraryUtil').checkType
local p = {}
local BODY_PARAM = '$B'
local specialParams = {
['$params'] = 'parameter list',
['$aliases'] = 'parameter aliases',
['$flags'] = 'flags',
['$format'] = 'date format',
['$B'] = 'template content'
}
function p.main(frame, body)
-- If we are substing, this function returns a template invocation, and if
-- not, it returns the template body. The template body can be specified in
-- the body parameter, or in the template parameter defined in the
-- BODY_PARAM variable. This function can be called from Lua or from
-- #invoke.
-- Return the template body if we aren't substing.
if not mw.isSubsting() then
if body ~= nil then
return body
elseif frame.args[BODY_PARAM] ~= nil then
return frame.args[BODY_PARAM]
else
error(string.format(
"no template content specified (use parameter '%s' from #invoke)",
BODY_PARAM
), 2)
end
end
-- Sanity check for the frame object.
if type(frame) ~= 'table'
or type(frame.getParent) ~= 'function'
or not frame:getParent()
then
error(
"argument #1 to 'main' must be a frame object with a parent " ..
"frame available",
2
)
end
-- Find the invocation name.
local mTemplateInvocation = require('Module:Template invocation')
local name = mTemplateInvocation.name(frame:getParent():getTitle())
-- Combine passed args with passed defaults
local args = {}
local format = frame.args['$format'] or 'j xg Y'
if string.find( ','..(frame.args['$flags'] or '')..',', ',%s*override%s*,' ) then
for k, v in pairs( frame:getParent().args ) do
args[k] = v
end
for k, v in pairs( frame.args ) do
if not specialParams[k] then
if v == '__DATE__' then
v = mw.getContentLanguage():formatDate( format )
end
args[k] = v
end
end
else
for k, v in pairs( frame.args ) do
if not specialParams[k] then
if v == '__DATE__' then
v = mw.getContentLanguage():formatDate( format )
end
args[k] = v
end
end
for k, v in pairs( frame:getParent().args ) do
args[k] = v
end
end
-- Trim parameters, if not specified otherwise
if not string.find( ','..(frame.args['$flags'] or '')..',', ',%s*keep%-whitespace%s*,' ) then
for k, v in pairs( args ) do args[k] = mw.ustring.match(v, '^%s*(.*)%s*$') or '' end
end
-- Pull information from parameter aliases
local aliases = {}
if frame.args['$aliases'] then
local list = mw.text.split( frame.args['$aliases'], '%s*,%s*' )
for k, v in ipairs( list ) do
local tmp = mw.text.split( v, '%s*>%s*' )
aliases[tonumber(mw.ustring.match(tmp[1], '^[1-9][0-9]*$')) or tmp[1]] = ((tonumber(mw.ustring.match(tmp[2], '^[1-9][0-9]*$'))) or tmp[2])
end
end
for k, v in pairs( aliases ) do
if args[k] and ( not args[v] or args[v] == '' ) then
args[v] = args[k]
end
args[k] = nil
end
-- Remove empty parameters, if specified
if string.find( ','..(frame.args['$flags'] or '')..',', ',%s*remove%-empty%s*,' ) then
local tmp = 0
for k, v in ipairs( args ) do
if v ~= '' or ( args[k+1] and args[k+1] ~= '' ) or ( args[k+2] and args[k+2] ~= '' ) then
tmp = k
else
break
end
end
for k, v in pairs( args ) do
if v == '' then
if not (type(k) == 'number' and k < tmp) then args[k] = nil end
end
end
end
-- Order parameters
if frame.args['$params'] then
local params, tmp = mw.text.split( frame.args['$params'], '%s*,%s*' ), {}
for k, v in ipairs(params) do
v = tonumber(mw.ustring.match(v, '^[1-9][0-9]*$')) or v
if args[v] then tmp[v], args[v] = args[v], nil end
end
for k, v in pairs(args) do tmp[k], args[k] = args[k], nil end
args = tmp
end
return mTemplateInvocation.invocation(name, args)
end
p[''] = p.main -- For backwards compatibility
return p
66516cd1b82c9c1f13ac5cc5b9a87e1c93242068
Модуль:Sidebar
828
81
135
134
2024-08-09T17:00:12Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
--
-- Этот модуль обеспечивает работу шаблона {{Sidebar}}
--
require('strict')
local p = {}
local getArgs = require('Модуль:Arguments').getArgs
local navbar = require('Модуль:Navbar')._navbar
local function trimAndAddAutomaticNewline(s)
-- For compatibility with the original {{sidebar with collapsible lists}}
-- implementation, which passed some parameters through {{#if}} to trim
-- their whitespace. This also triggered the automatic newline behavior.
-- ([[meta:Help:Newlines and spaces#Automatic newline]])
s = mw.ustring.gsub(s, "^%s*(.-)%s*$", "%1")
if mw.ustring.find(s, '^[#*:;]') or mw.ustring.find(s, '^{|') then
return '\n' .. s
else
return s
end
end
function p.sidebar(frame, args)
if not args then
args = getArgs(frame)
end
local root = mw.html.create()
local child = args.child and mw.text.trim(args.child) == 'yes'
if not child then
root = root
:tag('table')
:addClass('vertical-navbox')
:addClass(args.wraplinks ~= 'true' and 'nowraplinks' or nil)
:addClass(args.bodyclass or args.class)
:css('float', args.float or 'right')
:css('clear', (args.float == 'none' and 'both') or args.float or 'right')
:css('width', args.width or '22.0em')
:css('margin', args.float == 'left' and '0 1.0em 1.0em 0' or '0 0 1.0em 1.0em')
:css('background', '#f9f9f9')
:css('border', '1px solid #aaa')
:css('padding', '0.2em')
:css('border-spacing', '0.4em 0')
:css('text-align', 'center')
:css('line-height', '1.4em')
:css('font-size', '88%')
:cssText(args.bodystyle or args.style)
if args.outertitle then
root
:tag('caption')
:addClass(args.outertitleclass)
:css('padding-bottom', '0.2em')
:css('font-size', '125%')
:css('line-height', '1.2em')
:css('font-weight', 'bold')
:cssText(args.outertitlestyle)
:wikitext(args.outertitle)
end
if args.topimage then
local imageCell = root:tag('tr'):tag('td')
imageCell
:addClass(args.topimageclass)
:css('padding', '0.4em 0')
:cssText(args.topimagestyle)
:wikitext(args.topimage)
if args.topcaption then
imageCell
:tag('div')
:css('padding-top', '0.2em')
:css('line-height', '1.2em')
:cssText(args.topcaptionstyle)
:wikitext(args.topcaption)
end
end
if args.pretitle then
root
:tag('tr')
:tag('td')
:addClass(args.pretitleclass)
:cssText(args.basestyle)
:css('padding-top', args.topimage and '0.2em' or '0.4em')
:css('line-height', '1.2em')
:cssText(args.pretitlestyle)
:wikitext(args.pretitle)
end
end
if args.title then
if child then
root
:wikitext(args.title)
:wikitext('</th></tr>') -- @todo replace this with unclosed again once mw.html gets it
else
root
:tag('tr')
:tag('th')
:addClass(args.titleclass)
:cssText(args.basestyle)
:css('padding', '0.2em 0.4em 0.2em')
:css('padding-top', args.pretitle and 0)
:css('font-size', '145%')
:css('line-height', '1.2em')
:cssText(args.titlestyle)
:wikitext(args.title)
end
end
if args.image then
local imageCell = root:tag('tr'):tag('td')
imageCell
:addClass(args.imageclass)
:css('padding', '0.2em 0 0.4em')
:cssText(args.imagestyle)
:wikitext(args.image)
if args.caption then
imageCell
:tag('div')
:css('padding-top', '0.2em')
:css('line-height', '1.2em')
:cssText(args.captionstyle)
:wikitext(args.caption)
end
end
if args.above then
root
:tag('tr')
:tag('td')
:addClass(args.aboveclass)
:css('padding', '0.3em 0.4em 0.3em')
:css('font-weight', 'bold')
:cssText(args.abovestyle)
:newline() -- newline required for bullet-points to work
:wikitext(args.above)
end
local rowNums = {}
for k, v in pairs(args) do
k = '' .. k
local num = k:match('^heading(%d+)$') or k:match('^content(%d+)$')
if num then table.insert(rowNums, tonumber(num)) end
end
table.sort(rowNums)
-- remove duplicates from the list (e.g. 3 will be duplicated if both heading3 and content3 are specified)
for i = #rowNums, 1, -1 do
if rowNums[i] == rowNums[i - 1] then
table.remove(rowNums, i)
end
end
for i, num in ipairs(rowNums) do
local heading = args['heading' .. num]
if heading then
root
:tag('tr')
:tag('th')
:addClass(args.headingclass)
:css('padding', '0.1em')
:cssText(args.basestyle)
:cssText(args.headingstyle)
:cssText(args['heading' .. num .. 'style'])
:newline()
:wikitext(heading)
end
local content = args['content' .. num]
if content then
root
:tag('tr')
:tag('td')
:addClass(args.contentclass)
:css('padding', '0 0.1em 0.4em')
:cssText(args.contentstyle)
:cssText(args['content' .. num .. 'style'])
:newline()
:wikitext(content)
:done()
:newline() -- Without a linebreak after the </td>, a nested list like "* {{hlist| ...}}" doesn't parse correctly.
end
end
if args.below then
root
:tag('tr')
:tag('td')
:addClass(args.belowclass)
:css('padding', '0.3em 0.4em 0.3em')
:css('font-weight', 'bold')
:cssText(args.belowstyle)
:newline()
:wikitext(args.below)
end
if not child then
local navbarArg = args.navbar or args.tnavbar
if navbarArg ~= 'none' and navbarArg ~= 'off' and (args.name or frame:getParent():getTitle():gsub('/sandbox$', '') ~= 'Шаблон:Sidebar') then
root
:tag('tr')
:tag('td')
:css('text-align', 'right')
:css('font-size', '115%')
:cssText(args.navbarstyle or args.tnavbarstyle)
:wikitext(navbar{
args.name,
mini = 1,
fontstyle = args.navbarfontstyle or args.tnavbarfontstyle
})
end
end
return tostring(root)
end
function p.collapsible(frame)
local args = getArgs(frame)
args.abovestyle = 'border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;' .. (args.abovestyle or '')
args.belowstyle = 'border-top: 1px solid #aaa; border-bottom: 1px solid #aaa;' .. (args.belowstyle or '')
args.navbarstyle = 'padding-top: 0.6em;' .. (args.navbarstyle or args.tnavbarstyle or '')
if not args.name and frame:getParent():getTitle():gsub('/sandbox$', '') == 'Шаблон:Sidebar with collapsible lists' then
args.navbar = 'none'
end
local contentArgs = {}
for k, v in pairs(args) do
local num = string.match(k, '^list(%d+)$')
if num then
local expand = args.expanded and (args.expanded == 'all' or args.expanded == args['list' .. num .. 'name'])
local row = mw.html.create('div')
row
:addClass('NavFrame')
:addClass((not expand) and 'collapsed' or nil)
:css('border', 'none')
:css('padding', 0)
:cssText(args.listframestyle)
:cssText(args['list' .. num .. 'framestyle'])
:tag('div')
:addClass('NavHead')
:addClass(args.listtitleclass)
:css('font-size', '105%')
:css('background', 'transparent')
:css('text-align', 'left')
:cssText(args.basestyle)
:cssText(args.listtitlestyle)
:cssText(args['list' .. num .. 'titlestyle'])
:wikitext(trimAndAddAutomaticNewline(args['list' .. num .. 'title'] or 'List'))
:done()
:tag('div')
:addClass('NavContent')
:addClass(args.listclass)
:addClass(args['list' .. num .. 'class'])
:css('font-size', '105%')
:css('padding', '0.2em 0 0.4em')
:css('text-align', 'center')
:cssText(args.liststyle)
:cssText(args['list' .. num .. 'style'])
:wikitext(trimAndAddAutomaticNewline(args['list' .. num]))
contentArgs['content' .. num] = tostring(row)
end
end
for k, v in pairs(contentArgs) do
args[k] = v
end
return p.sidebar(frame, args)
end
return p
e8d033060367055f925583e3102d31899d0dce9d
Модуль:Navbox
828
82
139
138
2024-08-09T17:05:21Z
Ксеноморф
2
1 версия импортирована: Импортировано из Русской Википедии
Scribunto
text/plain
--
-- Реализует {{навигационная таблица}}, {{подгруппы навигационной таблицы}} и {{навигационная таблица с блоками}}.
-- Основной объём кода заимствован из английского Module:Navbox.
--
local p = {}
local navbar = require('Module:Navbar')._ruwikiNavbar
local getArgs -- lazily initialized
local yesno -- lazily initialized
local styleratio
local ODD_EVEN_MARKER = '\127_ODDEVEN_\127'
local RESTART_MARKER = '\127_ODDEVEN0_\127'
local REGEX_MARKER = '\127_ODDEVEN(%d?)_\127'
-- общие параметры для всех шаблонов
local commonAliases = {
name = {'name', 'имя'},
navigation = {'navigation', 'навигация'},
navbar = {'navbar', 'ссылка_на_просмотр'},
state = {'state'},
orphan = {'orphan'},
tracking = {'tracking'},
border = {'border', 1},
title = {'title', 'заголовок'},
titlegroup = {'titlegroup'},
above = {'above', 'вверху'},
image = {'image', 'изображение'},
imageleft = {'imageleft', 'изображение2', 'изображение_слева'},
below = {'below', 'внизу'},
bodyclass = {'bodyclass', 'класс_тела'},
titleclass = {'titleclass', 'класс_заголовка'},
titlegroupclass = {'titlegroupclass'},
aboveclass = {'aboveclass', 'класс_вверху'},
belowclass = {'belowclass', 'класс_внизу'},
groupclass = {'groupclass', 'класс_групп'},
listclass = {'listclass', 'класс_списков'},
imageclass = {'imageclass', 'класс_изображения'},
basestyle = {'basestyle', 'стиль', 'стиль_базовый'},
bodystyle = {'style', 'bodystyle', 'стиль_тела'},
titlestyle = {'titlestyle', 'стиль_основного_заголовка', 'стиль_заголовка'},
titlegroupstyle = {'titlegroupstyle'},
innerstyle = {'innerstyle'},
abovestyle = {'abovestyle', 'стиль_вверху'},
belowstyle = {'belowstyle', 'стиль_внизу'},
imagestyle = {'imagestyle', 'стиль_изображения'},
imageleftstyle = {'imageleftstyle', 'imagestyle2', 'стиль_изображения_слева'},
}
-- параметры {{навигационная таблица}} и {{подгруппы навигационной таблицы}}
local standardAliases = {
groupstyle = {'groupstyle', 'стиль_заголовков', 'стиль_групп'},
liststyle = {'liststyle', 'стиль_списков'},
evenodd = {'evenodd', 'чётные_нечётные', 'четные_нечетные'},
groupwidth = {'groupwidth', 'ширина_групп'},
listpadding = {'listpadding', 'отступ_списков'},
}
-- параметры {{навигационная таблица}} и {{подгруппы навигационной таблицы}} с нумерацией
local standardElementAliases = {
group = {'group%s', 'заголовок%s', 'группа%s'},
list = {'list%s', 'список%s'},
groupstyle = {'group%sstyle', 'стиль_заголовка%s', 'стиль_группы%s'},
listclass = {'list%sclass', 'класс%sсписка', 'класс_списка%s'},
liststyle = {'list%sstyle', 'стиль_списка%s'},
listpadding = {'list%spadding'}
}
-- параметры {{навигационная таблица с блоками}}
-- с нижнего подчеркивания начинаются параметры, конфликтующие с standardAliases
local groupsParentAliases = {
selected = {'selected', 'открытый_блок', 'развернуть'},
secttitlestyle = {'secttitlestyle', 'стиль_заголовков'},
_groupstyle = {'groupstyle', 'стиль_блоков'},
_liststyle = {'liststyle', 'стиль_списков', 'contentstyle'},
_listpadding = {'listpadding', 'отступ_списка', 'отступ_списков'}
}
-- параметры {{навигационная таблица с блоками}} с нумерацией
local groupsChildAliases = {
groupname = {'abbr%s', 'имя_блока%s', 'аббр%s'},
state = {'state%s'},
title = {'group%s', 'блок%s', 'заголовок%s', 'группа%s', 'sect%s', 'section%s', 'секция%s'},
list1 = {'list%s', 'список%s', 'content%s'},
image = {'image%s', 'изображение%s'},
imageleft = {'imageleft%s', 'изображение_слева%s'},
secttitlestyle = {'sect%stitlestyle', 'стиль%sзаголовка', 'стиль_секции%s'},
groupstyle = {'group%sstyle', 'стиль%sблока', 'стиль_группы%s', 'стиль_блока%s'},
listclass = {'list%sclass', 'класс%sсписка', 'класс_списка%s'},
liststyle = {'list%sstyle', 'стиль%sсписка', 'стиль_списка%s', 'content%sstyle'},
color = {'цвет%s'}
}
local function checkAliases(args, aliases, index)
for _, alias in ipairs(aliases) do
local arg
if index then
arg = args[string.format(alias, index)]
else
arg = args[alias]
end
if arg then
return arg
end
end
return nil
end
local function checkElAliases(args, name, index)
return checkAliases(args, standardElementAliases[name], index)
end
local function concatStyles(t)
local res
for k, v in pairs(t) do
if v then
res = res and res .. ';' .. v or v
end
end
return res
end
local function striped(wikitext, args)
-- Return wikitext with markers replaced for odd/even striping.
-- Child (subgroup) navboxes are flagged with a category that is removed
-- by parent navboxes. The result is that the category shows all pages
-- where a child navbox is not contained in a parent navbox.
local orphanCat = '[[Категория:Навигационные шаблоны без родителя]]'
if args.border == 'subgroup' and args.orphan ~= 'yes' then
-- No change; striping occurs in outermost navbox.
return wikitext .. orphanCat
end
local first, second = 'odd', 'even'
if args.evenodd then
if args.evenodd == 'swap' then
first, second = second, first
else
first = args.evenodd
second = first
end
end
local changer
if first == second then
changer = first
else
local index = 0
changer = function (code)
if code == '0' then
-- Current occurrence is for a group before a nested table.
-- Set it to first as a valid although pointless class.
-- The next occurrence will be the first row after a title
-- in a subgroup and will also be first.
index = 0
return first
end
index = index + 1
return index % 2 == 1 and first or second
end
end
local regex = orphanCat:gsub('([%[%]])', '%%%1')
return (wikitext:gsub(regex, ''):gsub(REGEX_MARKER, changer)) -- () omits gsub count
end
local function addNewline(s)
if s:match('^[*:;#]') or s:match('^{|') then
return '\n' .. s ..'\n'
else
return s
end
end
local function renderNavBar(titleCell, args)
local currentFrame = mw.getCurrentFrame()
if args.navbar ~= 'off' and args.navbar ~= 'plain'
and (args.name or not currentFrame:getParent():getTitle():gsub('/песочница$', '') == 'Шаблон:Навигационная таблица') then
--- Gear creation
titleCell
:tag('span')
:addClass('navbox-gear')
:css('float', 'left')
:css('text-align', 'left')
:css('width', '5em')
:css('margin-right', '0.5em')
:wikitext(navbar{
args.name,
['fontstyle'] = args.titlestyle or args.basestyle
})
end
end
--
-- Title row
--
local function renderTitleRow(tbl, args)
if not args.title then return end
local titleRow = tbl:tag('tr')
if args.titlegroup then
titleRow
:tag('th')
:attr('scope', 'row')
:addClass('navbox-group')
:addClass(args.titlegroupclass)
:cssText(args.basestyle)
:cssText(args.groupstyle)
:cssText(args.titlegroupstyle)
:wikitext(args.titlegroup)
end
local titleCell = titleRow:tag('th'):attr('scope', 'colgroup')
if args.titlegroup then
titleCell
:css('border-left', '2px solid #fdfdfd')
:css('width', '100%')
end
local titleColspan = 2
if args.imageleft then titleColspan = titleColspan + 1 end
if args.image then titleColspan = titleColspan + 1 end
if args.titlegroup then titleColspan = titleColspan - 1 end
titleCell
:cssText(args.basestyle)
:cssText(args.titlestyle)
:addClass('navbox-title')
:attr('colspan', titleColspan)
renderNavBar(titleCell, args)
titleCell
:tag('div')
:attr('id', mw.uri.anchorEncode(args.title))
:addClass(args.titleclass)
:css('font-size', '114%')
:css('margin', '0 5em')
:wikitext(addNewline(args.title))
end
--
-- Above/Below rows
--
local function getAboveBelowColspan(args)
local ret = 2
if args.imageleft then ret = ret + 1 end
if args.image then ret = ret + 1 end
return ret
end
local function renderAboveRow(tbl, args)
if not args.above then return end
tbl:tag('tr')
:tag('td')
:addClass('navbox-abovebelow')
:addClass(args.aboveclass)
:cssText(args.basestyle)
:cssText(args.abovestyle)
:attr('colspan', getAboveBelowColspan(args))
:tag('div')
:wikitext(addNewline(args.above))
end
local function renderBelowRow(tbl, args)
if not args.below then return end
tbl:tag('tr')
:tag('td')
:addClass('navbox-abovebelow')
:addClass(args.belowclass)
:cssText(args.basestyle)
:cssText(args.belowstyle)
:attr('colspan', getAboveBelowColspan(args))
:tag('div')
:wikitext(addNewline(args.below))
end
--
-- List rows
--
local function haveSubgroups(args)
for i = 1, 23 do
if checkElAliases(args, 'group', i) and checkElAliases(args, 'list', i) then
return true
end
end
return false
end
local function renderListRow(tbl, args, index, rowspan, rowArgs)
local row = tbl:tag('tr')
if index == 1 and args.imageleft then
row
:tag('td')
:addClass('navbox-image')
:addClass(args.imageclass)
:css('width', '1px')
:css('padding', '0px 7px 0px 0px')
:cssText(args.imageleftstyle)
:attr('rowspan', rowspan)
:tag('div')
:wikitext(addNewline(args.imageleft))
end
if rowArgs.group then
local groupCell = row:tag('th')
groupCell
:attr('scope', 'row')
:addClass('navbox-group')
:addClass(args.groupclass)
:cssText(args.basestyle)
:css('width', args.groupwidth or '1px') -- If groupwidth not specified, minimize width
groupCell
:cssText(args.groupstyle)
:cssText(rowArgs.groupstyle)
:wikitext(rowArgs.group)
end
local listCell = row:tag('td')
if rowArgs.group then
listCell
:css('text-align', 'left')
:css('border-left-width', '2px')
:css('border-left-style', 'solid')
else
if haveSubgroups(args) then
listCell
:attr('colspan', 2)
end
end
if not args.groupwidth then
listCell:css('width', '100%')
end
local listText = rowArgs.list
local oddEven = ODD_EVEN_MARKER
if listText:sub(1, 12) == '</div><table' then
-- Assume list text is for a subgroup navbox so no automatic striping for this row.
oddEven = listText:find('<th[^>]*"navbox%-title"') and RESTART_MARKER or 'odd'
end
listCell
:css('padding', '0px')
:cssText(args.liststyle)
:cssText(rowArgs.liststyle)
:addClass('navbox-list')
:addClass('navbox-' .. oddEven)
:addClass(args.listclass)
:addClass(rowArgs.listclass)
:tag('div')
:css('padding', rowArgs.listpadding or args.listpadding or '0em 0.25em')
:wikitext(addNewline(listText))
if index == 1 and args.image then
row
:tag('td')
:addClass('navbox-image')
:addClass(args.imageclass)
:css('width', '1px')
:css('padding', '0px 0px 0px 7px')
:cssText(args.imagestyle)
:attr('rowspan', rowspan)
:tag('div')
:wikitext(addNewline(args.image))
end
end
--
-- Tracking categories
--
local function needsChangetoSubgroups(args)
for i = 1, 23 do
if (checkElAliases(args, 'group', i)) and not (checkElAliases(args, 'list', i)) then
return true
end
end
return false
end
local function needsHorizontalLists(args)
if args.border == 'subgroup' or args.tracking == 'no' then
return false
end
local listClasses = {
['plainlist'] = true, ['hlist'] = true, ['hlist hnum'] = true,
['hlist hwrap'] = true, ['hlist vcard'] = true, ['vcard hlist'] = true,
['hlist vevent'] = true, ['hlist hlist-items-nowrap'] = true, ['hlist-items-nowrap'] = true,
}
return not (listClasses[args.listclass] or listClasses[args.bodyclass])
end
-- local function hasBackgroundColors()
-- return mw.ustring.match(titlestyle or '','background') or mw.ustring.match(groupstyle or '','background') or mw.ustring.match(basestyle or '','background')
-- end
local function isIllegible(args)
if not styleratio then
styleratio = require('Module:Color contrast')._styleratio
end
for key, style in pairs(args) do
if tostring(key):match("style$") or tostring(key):match("^стиль") then
if styleratio{mw.text.unstripNoWiki(style)} < 4.5 then
return true
end
end
end
return false
end
local function getTrackingCategories(args)
local cats = {}
if needsChangetoSubgroups(args) then table.insert(cats, 'Навигационные шаблоны с ошибочным использованием заголовков') end
if needsHorizontalLists(args) then table.insert(cats, 'Навигационные шаблоны без горизонтальных списков') end
if isIllegible(args) then table.insert(cats, 'Потенциально нечитаемые навигационные шаблоны') end
return cats
end
local function renderTrackingCategories(builder, args)
local title = mw.title.getCurrentTitle()
if title.namespace ~= 10 then return end -- not in template space
local subpage = title.subpageText
if subpage == 'doc' or subpage == 'песочница' or subpage == 'тесты' then return end
for i, cat in ipairs(getTrackingCategories(args)) do
builder:wikitext('[[Категория:' .. cat .. ']]')
end
end
--
-- Main navbox tables
--
local function renderMainTable(args, listnums)
local tbl = mw.html.create('table')
:addClass('nowraplinks')
:addClass(args.bodyclass)
if args.title and (args.state ~= 'plain' and args.state ~= 'off') then
tbl
:addClass('collapsible')
:addClass(args.state or 'autocollapse')
end
tbl:css('border-spacing', 0)
if args.border == 'subgroup' or args.border == 'none' then
tbl
:addClass('navbox-subgroup')
:cssText(args.bodystyle)
else -- regular navbox - bodystyle and style will be applied to the wrapper table
tbl
:addClass('navbox-inner')
:css('background', 'transparent')
:css('color', 'inherit')
end
tbl:cssText(args.innerstyle)
renderTitleRow(tbl, args)
renderAboveRow(tbl, args)
for i, listnum in ipairs(listnums) do
local rowArgs = {
group = checkElAliases(args, 'group', listnum),
list = checkElAliases(args, 'list', listnum),
groupstyle = checkElAliases(args, 'groupstyle', listnum),
listclass = checkElAliases(args, 'listclass', listnum),
liststyle = checkElAliases(args, 'liststyle', listnum),
listpadding = checkElAliases(args, 'listpadding', listnum)
}
renderListRow(tbl, args, i, #listnums, rowArgs)
end
renderBelowRow(tbl, args)
return tbl
end
-- Read the arguments in the order they'll be output in, to make references number in the right order.
local function readInTheRightOrder(args, groupAliases, listAliases)
local _
_ = checkAliases(args, commonAliases.title)
_ = checkAliases(args, commonAliases.above)
for i = 1, 23 do
_ = checkAliases(args, groupAliases, i)
_ = checkAliases(args, listAliases, i)
end
_ = checkAliases(args, commonAliases.below)
end
function p._navbox(args)
if not yesno then
yesno = require('Module:Yesno')
end
local listnums = {}
for k, v in pairs(args) do
local listnum = ('' .. k):match('^list(%d+)$') or ('' .. k):match('^список(%d+)$')
if listnum then table.insert(listnums, tonumber(listnum)) end
end
table.sort(listnums)
args.border = mw.text.trim(args.border or args[1] or '')
if args.border == 'child' then
args.border = 'subgroup'
end
for argname, aliasesList in pairs(commonAliases) do
args[argname] = checkAliases(args, aliasesList)
end
for argname, aliasesList in pairs(standardAliases) do
args[argname] = checkAliases(args, aliasesList)
end
args.navigation = yesno(args.navigation, '')
-- render the main body of the navbox
local tbl = renderMainTable(args, listnums)
-- render the appropriate wrapper around the navbox, depending on the border param
local res = mw.html.create()
if args.border == 'none' then
local nav = res:tag('div')
:attr('role', 'navigation')
:node(tbl)
if args.title then
nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title))
else
nav:attr('aria-label', 'Навигационный шаблон')
end
if args.name and args.name ~= '-' then
nav:attr('data-name', args.name)
end
if args.navigation == true then
nav:attr('data-navboxnavigation', '1')
elseif args.navigation == false then
nav:attr('data-navboxnavigation', '0')
end
elseif args.border == 'subgroup' then
-- We assume that this navbox is being rendered in a list cell of a parent navbox, and is
-- therefore inside a div with padding:0em 0.25em. We start with a </div> to avoid the
-- padding being applied, and at the end add a <div> to balance out the parent's </div>
res
:wikitext('</div>') -- XXX: hack due to lack of unclosed support in mw.html.
:node(tbl)
:wikitext('<div>') -- XXX: hack due to lack of unclosed support in mw.html.
else
local nav = res:tag('div')
:attr('role', 'navigation')
:addClass('navbox')
:cssText(args.bodystyle)
:node(tbl)
if args.title then
nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title))
else
nav:attr('aria-label', 'Навигационный шаблон')
end
if args.name and args.name ~= '-' then
nav:attr('data-name', args.name)
end
if args.navigation == true then
nav:attr('data-navboxnavigation', '1')
elseif args.navigation == false then
nav:attr('data-navboxnavigation', '0')
end
end
renderTrackingCategories(res, args)
return striped(tostring(res), args)
end
function p.navbox(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
if not yesno then
yesno = require('Module:Yesno')
end
args = getArgs(frame, {wrappers = {'Шаблон:Навигационная таблица', 'Шаблон:Подгруппы навигационной таблицы'}})
if frame.args.border then
-- This allows Template:Navbox_subgroup to use {{#invoke:Navbox|navbox|border=...}}.
args.border = frame.args.border
end
readInTheRightOrder(args, standardElementAliases.group, standardElementAliases.list)
return p._navbox(args)
end
function p.navboxWithCollapsibleGroups(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
local args = getArgs(frame, {wrappers = {'Шаблон:Навигационная таблица с блоками'}})
readInTheRightOrder(args, groupsChildAliases.title, groupsChildAliases.list1)
local parent = {}
for argname, aliasesList in pairs(commonAliases) do
parent[argname] = checkAliases(args, aliasesList)
end
for argname, aliasesList in pairs(groupsParentAliases) do
parent[argname] = checkAliases(args, aliasesList)
end
for i = 1, 20 do
local child = {}
for argname, aliasesList in pairs(groupsChildAliases) do
child[argname] = checkAliases(args, aliasesList, i)
end
child.color = child.color and string.format('background:%s;', child.color) or ''
child.border = 'child'
child.navbar = 'plain'
if parent.selected and parent.selected == child.groupname then
child.state = 'uncollapsed'
end
child.state = child.state or 'collapsed'
child.basestyle = concatStyles{parent.basestyle, parent.secttitlestyle, child.secttitlestyle}
child.titlestyle = concatStyles{parent._groupstyle, child.groupstyle, child.color}
child.liststyle = concatStyles{parent._liststyle, child.liststyle}
child.lispadding = parent._listpadding
if child.title then
parent['list' .. i] = p._navbox(child)
else
parent['list' .. i] = child.list1
end
end
return p._navbox(parent)
end
return p
cf72974326d19e1d4d58d2d00766b944b3ca0944
Модуль:Карточка
828
83
141
140
2024-08-09T17:11:07Z
Ксеноморф
2
1 версия импортирована: Импортировано из Русской Википедии
Scribunto
text/plain
--
-- Модуль для реализации шаблона {{Карточка}}
--
local p = {}
local HtmlBuilder = require('Module:HtmlBuilder')
local args = {}
local origArgs
local argsAliases = {}
local root
local function union(t1, t2)
-- Возвращает объединение значений двух таблиц в виде последовательности.
local vals = {}
for k, v in pairs(t1) do
vals[v] = true
end
for k, v in pairs(t2) do
vals[v] = true
end
local ret = {}
for k, v in pairs(vals) do
table.insert(ret, k)
end
return ret
end
local function getArgNums(prefix)
-- Возвращает таблицу индексов существующих полей с заданным префиксом,
-- например, для префикса 'текст' и установленных 'текст1', 'текст2' и
-- 'текст5' возвращает {1, 2, 5}.
local nums = {}
for k, v in pairs(args) do
local num = tostring(k):match('^' .. prefix .. '([1-9]%d*)$')
if num then table.insert(nums, tonumber(num)) end
end
table.sort(nums)
return nums
end
local function addRow(rowArgs)
-- Добавляет строку в карточку (заголовок или метку/текст).
if rowArgs.header then
root
.tag('tr')
.addClass(rowArgs.rowclass)
.attr('id', rowArgs.rowid)
.tag('th')
.attr('colspan', 2)
.attr('id', rowArgs.headerid)
.addClass(rowArgs.class)
.addClass(args['класс_заголовков'])
.css('text-align', 'center')
.cssText(args['стиль_заголовков'])
.wikitext(rowArgs.header)
elseif rowArgs.data then
local row = root.tag('tr')
row.addClass(rowArgs.rowclass)
row.attr('id', rowArgs.rowid)
if rowArgs.label then
row
.tag('th')
.attr('scope', 'row')
.attr('id', rowArgs.labelid)
.cssText(args['стиль_меток'])
.wikitext(rowArgs.label)
.done()
end
local dataCell = row.tag('td')
if not rowArgs.label then
dataCell
.attr('colspan', 2)
.css('text-align', 'center')
end
dataCell
.attr('id', rowArgs.dataid)
.addClass(rowArgs.class)
.cssText(rowArgs.datastyle)
.newline()
.wikitext(rowArgs.data)
end
end
local function renderTitle()
if not args['название'] then return end
root
.tag('caption')
.addClass(args['класс_названия'])
.cssText(args['стиль_названия'])
.wikitext(args['название'])
end
local function renderAboveRow()
if not args['вверху'] then return end
root
.tag('tr')
.tag('th')
.attr('colspan', 2)
.addClass(args['класс_вверху'])
.css('text-align', 'center')
.css('font-size', '125%')
.css('font-weight', 'bold')
.cssText(args['стиль_вверху'])
.wikitext(args['вверху'])
end
local function renderAbove2Row()
if not args['вверху2'] then return end
root
.tag('tr')
.tag('th')
.attr('colspan', 2)
.addClass(args['класс_вверху2'])
.css('text-align', 'center')
.css('font-style', 'oblique')
.cssText(args['стиль_вверху2'])
.wikitext(args['вверху2'])
end
local function renderBelowRow()
if not args['внизу'] then return end
root
.tag('tr')
.tag('td')
.attr('colspan', 2)
.addClass(args['класс_внизу'])
.css('text-align', 'center')
.cssText(args['стиль_внизу'])
.newline()
.wikitext(args['внизу'])
end
local function renderSubheaders()
if args['подзаголовок'] then
args['подзаголовок1'] = args['подзаголовок']
end
if args['класс_ряда_подзаголовка'] then
args['класс_ряда_подзаголовка1'] = args['класс_ряда_подзаголовка']
end
local subheadernums = getArgNums('подзаголовок')
for k, num in ipairs(subheadernums) do
addRow({
data = args['подзаголовок' .. tostring(num)],
datastyle = args['стиль_подзаголовков'] or args['стиль_подзаголовка' .. tostring(num)],
class = args['класс_подзаголовков'],
rowclass = args['класс_ряда_подзаголовка' .. tostring(num)]
})
end
end
local function renderImages()
if args['изображение'] then
args['изображение1'] = args['изображение']
end
if args['подпись'] then
args['подпись1'] = args['подпись']
end
local imagenums = getArgNums('изображение')
for k, num in ipairs(imagenums) do
local caption = args['подпись' .. tostring(num)]
local data = HtmlBuilder.create().wikitext(args['изображение' .. tostring(num)])
if caption then
data
.tag('div')
.cssText(args['стиль_подписи'])
.wikitext(caption)
end
addRow({
data = tostring(data),
datastyle = args['стиль_изображения'],
class = args['класс_изображения'],
rowclass = args['класс_ряда_изображения' .. tostring(num)]
})
end
end
local function renderRows()
-- Объединяет индексы заголовков и текстовых строк карточки
-- и визуализирует их в правильном порядке через addRow.
local rownums = union(getArgNums('заголовок'), getArgNums('текст'))
table.sort(rownums)
for k, num in ipairs(rownums) do
addRow({
header = args['заголовок' .. tostring(num)],
label = args['метка' .. tostring(num)],
data = args['текст' .. tostring(num)],
datastyle = args['стиль_текста'],
class = args['класс' .. tostring(num)],
rowclass = args['класс_ряда' .. tostring(num)],
dataid = args['id_текста' .. tostring(num)],
labelid = args['id_метки' .. tostring(num)],
headerid = args['id_заголовка' .. tostring(num)],
rowid = args['id_ряда' .. tostring(num)]
})
end
end
local function renderNavBar()
if not args['имя'] then return end
root
.tag('tr')
.tag('td')
.attr('colspan', 2)
.css('text-align', 'right')
.wikitext(mw.getCurrentFrame():expandTemplate({
title = 'Tnavbar',
args = { args['имя'] }
}))
end
local function isSet(x)
-- Возвращает истину, если x задан и не пустой
-- Внимание: отличается от enwiki! В enwiki проверяется на равенство 'yes'
return x and x ~= ''
end
local function renderItalicTitle()
-- Внимание: отличается от enwiki. В enwiki ожидается yes или force, здесь работает любое значение
if isSet(args['заголовок_курсивом']) then
root.wikitext(mw.getCurrentFrame():expandTemplate({title = 'Заголовок курсивом'}))
end
end
local function renderTrackingCategories()
if not isSet(args.nocat) then
if #(getArgNums('текст')) == 0 and mw.title.getCurrentTitle().namespace == 0 then
root.wikitext('[[Категория:Статьи с карточкой без заполненных данных]]')
end
if isSet(args['внедрение']) and args['название'] then
root.wikitext('[[Категория:Статьи со встроенной карточкой и параметром названия]]')
end
end
end
local function _infobox()
-- Задание общей страктуры карточки с добавлением стилей
-- для карточек-потомков.
if not isSet(args['внедрение']) then
root = HtmlBuilder.create('table')
root
.addClass('infobox')
.addClass(args['класс_тела'])
if isSet(args['подкарточка']) then
root
.css('padding', '0')
.css('border', 'none')
.css('margin', '-2px')
.css('width', 'auto')
.css('min-width', '100%')
.css('font-size', '100%')
.css('clear', 'none')
.css('float', 'none')
.css('background-color', 'transparent')
end
-- Микроразметка
if isSet(args['микр_тела']) then
root
.attr('itemscope', 'itemscope')
.attr('itemtype', args['микр_тела'])
end
root
.cssText(args['стиль_тела'])
renderTitle()
renderAboveRow()
renderAbove2Row()
else
root = HtmlBuilder.create()
root
.wikitext(args['название'])
end
renderSubheaders()
renderImages()
renderRows()
renderBelowRow()
renderNavBar()
renderItalicTitle()
renderTrackingCategories()
return tostring(root)
end
local function preprocessSingleArg(argName)
-- Добавляет аргумент в таблицу аргументов, если он определён и не пустой.
-- Пустые аргументы не обрабатываются, как и в ParserFunctions.
if origArgs[argName] and origArgs[argName] ~= '' then
args[argName] = origArgs[argName]
end
end
local function translateArg(aliasArgName,localArgName)
-- Функция добавляет поддержку алиасов параметров (например, на другом языке)
-- Добавляем алиас параметра в таблицу алиасов
-- Для одного параметра может быть несколько алиасов
-- Нумерованные параметры(текст1 и т.д.) заносятся без номера
if not argsAliases[localArgName] then
argsAliases[localArgName] = {}
end
table.insert(argsAliases[localArgName], aliasArgName)
-- Пока для тестирования: значения алиасов добавляются в таблицу аргументов
-- Нумерованные параметры работать не будут
if origArgs[localArgName] and origArgs[localArgName] ~= '' then
-- параметр уже задан на локальном языке
else
-- если алиас задан и не пустой
if origArgs[aliasArgName] and origArgs[aliasArgName] ~= '' then
origArgs[localArgName] = origArgs[aliasArgName]
end
end
end
local function preprocessArgs(prefixTable, step)
-- Сохраняет параметры с заданными префиксами в таблицу args, последовательно обходя
-- аргументы в нужном порядке и с нужным шагом. Благодаря этому сноски и пр. появляются
-- в правильном порядке. prefixTable — массив таблиц, каждая из которых может содержать
-- два поля: поле-строку префикса (обязательно) и поле-таблицу зависимых параметров.
-- Эта функция всегда обрабатывает параметры с префиксом, но зависимые параметры
-- обрабатываются, только если параметр с префиксом задан и не пустой.
if type(prefixTable) ~= 'table' then
error("В качестве таблицы префиксов должна использоваться таблица", 2)
end
if type(step) ~= 'number' then
error("Недопустимый тип параметра шага", 2)
end
-- Проверка правильности данных и обработка параметров без суффиксов.
for i,v in ipairs(prefixTable) do
if type(v) ~= 'table' or type(v.prefix) ~= "string" or (v.depend and type(v.depend) ~= 'table') then
error('Недопустимая таблица префиксов preprocessArgs', 2)
end
preprocessSingleArg(v.prefix)
-- Зависимые параметры обрабатываются, только если параметр с префиксом задан и не пустой.
if args[v.prefix] and v.depend then
for j, dependValue in ipairs(v.depend) do
if type(dependValue) ~= 'string' then
error('Недопустимый тип зависимого параметра в таблице preprocessArgs')
end
preprocessSingleArg(dependValue)
end
end
end
-- Обход нумерованных аргументов.
local a = 1 -- Переменная-счётчик.
local moreArgumentsExist = true
while moreArgumentsExist == true do
moreArgumentsExist = false
for i = a, a + step - 1 do
for j,v in ipairs(prefixTable) do
local prefixArgName = v.prefix .. tostring(i)
if origArgs[prefixArgName] then
moreArgumentsExist = true -- Искать аргументы дальше, если был хотя бы один (в т. ч. пустой)
preprocessSingleArg(prefixArgName)
end
-- Обрабатываем зависимые аргументы, если определена таблица зависимостей,
-- а также задан не пустой аргумент с префиксом, либо обрабатывается
-- "префикс1" и "префикс" задан (например, "изображение1" является синонимом для "изображение").
if v.depend and (args[prefixArgName] or (i == 1 and args[v.prefix])) then
for j,dependValue in ipairs(v.depend) do
local dependArgName = dependValue .. tostring(i)
preprocessSingleArg(dependArgName)
end
end
end
end
a = a + step
end
end
function p.infobox(frame)
-- При запуске через #invoke аргументы передаются через стандартную систему.
-- При тестировании также можно передавать таблицу аргументов через frame.
if frame == mw.getCurrentFrame() then
origArgs = frame:getParent().args
else
origArgs = frame
end
-- Поддержка параметров из англовики
translateArg('child','внедрение')
translateArg('bodyclass','класс_тела')
translateArg('subbox','подкарточка')
translateArg('bodystyle','стиль_тела')
translateArg('title','название')
translateArg('titleclass','класс_названия')
translateArg('titlestyle','стиль_названия')
translateArg('above','вверху')
translateArg('aboveclass','класс_вверху')
translateArg('abovestyle','стиль_вверху')
translateArg('subheader','подзаголовок')
translateArg('subheaderrowstyle','стиль_подзаголовка')
translateArg('subheaderrowclass','класс_подзаголовка')
translateArg('subheaderstyle','стиль_подзаголовков')
translateArg('subheaderclass','класс_подзаголовков')
translateArg('image','изображение')
translateArg('caption','подпись')
translateArg('imagerowclass','класс_ряда_изображения')
translateArg('captionstyle','стиль_подписи')
translateArg('imagestyle','стиль_изображения')
translateArg('imageclass','класс_изображения')
translateArg('header','заголовок')
translateArg('data','текст')
translateArg('label','метка')
translateArg('rowclass','класс_ряда')
translateArg('class','класс')
translateArg('dataid','id_текста')
translateArg('labelid','id_метки')
translateArg('headerid','id_заголовка')
translateArg('rowid','id_ряда')
translateArg('headerclass','класс_заголовков')
translateArg('headerstyle','стиль_заголовков')
translateArg('labelstyle','стиль_меток')
translateArg('datastyle','стиль_текста')
translateArg('below','внизу')
translateArg('belowclass','класс_внизу')
translateArg('belowstyle','стиль_внизу')
translateArg('name','имя')
--translateArg('italic title','заголовок_курсивом')
--translateArg('','')
-- Параметры обрабатываются по направлению чтения карточки, чтобы
-- сноски и др. отображались в нужных местах. Параметры, зависящие
-- от других параметров, обрабатываются только при наличии других параметров,
-- чтобы в списке сносок не возникали нежелательные сноски.
preprocessSingleArg('внедрение')
preprocessSingleArg('класс_тела')
preprocessSingleArg('подкарточка')
preprocessSingleArg('стиль_тела')
preprocessSingleArg('название')
preprocessSingleArg('класс_названия')
preprocessSingleArg('стиль_названия')
preprocessSingleArg('вверху')
preprocessSingleArg('класс_вверху')
preprocessSingleArg('стиль_вверху')
preprocessSingleArg('вверху2')
preprocessSingleArg('класс_вверху2')
preprocessSingleArg('стиль_вверху2')
preprocessArgs({
{prefix = 'подзаголовок', depend = {'стиль_подзаголовка', 'класс_подзаголовка'}}
}, 10)
preprocessSingleArg('стиль_подзаголовков')
preprocessSingleArg('класс_подзаголовков')
preprocessArgs({
{prefix = 'изображение', depend = {'подпись', 'класс_ряда_изображения'}}
}, 10)
preprocessSingleArg('стиль_подписи')
preprocessSingleArg('стиль_изображения')
preprocessSingleArg('класс_изображения')
preprocessArgs({
{prefix = 'заголовок'},
{prefix = 'текст', depend = {'метка'}},
{prefix = 'класс_ряда'},
{prefix = 'класс'},
{prefix = 'id_текста'},
{prefix = 'id_метки'},
{prefix = 'id_заголовка'},
{prefix = 'id_ряда'}
}, 50)
preprocessSingleArg('класс_заголовков')
preprocessSingleArg('стиль_заголовков')
preprocessSingleArg('стиль_меток')
preprocessSingleArg('стиль_текста')
preprocessSingleArg('внизу')
preprocessSingleArg('класс_внизу')
preprocessSingleArg('стиль_внизу')
preprocessSingleArg('имя')
preprocessSingleArg('заголовок_курсивом')
preprocessSingleArg('nocat')
return _infobox()
end
return p
2c8d650c985ea4b045be261f1a7a32917dfba56f
Модуль:InfoboxImage
828
84
143
142
2024-08-09T17:12:19Z
Ксеноморф
2
1 версия импортирована: Импортировано из Русской Википедии
Scribunto
text/plain
-- Inputs:
-- image - Can either be a bare filename (with or without the File:/Image: prefix) or a fully formatted image link
-- size - size to display the image
-- maxsize - maximum size for image
-- sizedefault - default size to display the image if size param is blank
-- alt - alt text for image
-- title - title text for image
-- border - set to yes if border
-- center - set to yes, if the image has to be centered
-- upright - upright image param
-- suppressplaceholder - if yes then checks to see if image is a placeholder and suppresses it
-- Outputs:
-- Formatted image.
-- More details available at the "Module:InfoboxImage/doc" page
local i = {};
local yesno = require('Module:Yesno');
local placeholder_image = {
"Blue - Replace this image female.svg",
"Blue - Replace this image male.svg",
"Female no free image yet.png",
"Flag of None (square).svg",
"Flag of None.svg",
"Flag of.svg",
"Green - Replace this image female.svg",
"Green - Replace this image male.svg",
"Image is needed female.svg",
"Image is needed male.svg",
"Location map of None.svg",
"Male no free image yet.png",
"Missing flag.png",
"No flag.svg",
"No free portrait.svg",
"No portrait (female).svg",
"No portrait (male).svg",
"Red - Replace this image female.svg",
"Red - Replace this image male.svg",
"Replace this image female (blue).svg",
"Replace this image female.svg",
"Replace this image male (blue).svg",
"Replace this image male.svg",
"Silver - Replace this image female.svg",
"Silver - Replace this image male.svg",
}
function i.IsPlaceholder(image)
-- change underscores to spaces
image = mw.ustring.gsub(image, "_", " ");
-- if image starts with [[ then remove that and anything after |
if mw.ustring.sub(image,1,2) == "[[" then
image = mw.ustring.sub(image,3);
image = mw.ustring.gsub(image, "([^|]*)|.*", "%1");
end
-- Trim spaces
image = mw.ustring.gsub(image, '^[ ]*(.-)[ ]*$', '%1');
-- remove file: or image: prefix if exists
if mw.ustring.lower(mw.ustring.sub(image,1,5)) == "file:" then
image = mw.ustring.sub(image,6);
end
if mw.ustring.lower(mw.ustring.sub(image,1,6)) == "image:" then
image = mw.ustring.sub(image,7);
end
-- Trim spaces
image = mw.ustring.gsub(image, '^[ ]*(.-)[ ]*$', '%1');
-- capitalise first letter
image = mw.ustring.upper(mw.ustring.sub(image,1,1)) .. mw.ustring.sub(image,2);
for i,j in pairs(placeholder_image) do
if image == j then
return true
end
end
return false
end
function i.InfoboxImage(frame)
local image = frame.args["image"];
if image == "" or image == nil then
return "";
end
if image == " " then
return image;
end
if frame.args["suppressplaceholder"] == "yes" then
if i.IsPlaceholder(image) == true then
return "";
end
end
if mw.ustring.lower(mw.ustring.sub(image,1,5)) == "http:" then
return "";
end
if mw.ustring.lower(mw.ustring.sub(image,1,6)) == "[http:" then
return "";
end
if mw.ustring.lower(mw.ustring.sub(image,1,7)) == "[[http:" then
return "";
end
if mw.ustring.lower(mw.ustring.sub(image,1,6)) == "https:" then
return "";
end
if mw.ustring.lower(mw.ustring.sub(image,1,7)) == "[https:" then
return "";
end
if mw.ustring.lower(mw.ustring.sub(image,1,8)) == "[[https:" then
return "";
end
if mw.ustring.sub(image,1,2) == "[[" then
-- search for thumbnail images and add to tracking cat if found
if mw.title.getCurrentTitle().namespace == 0 and (mw.ustring.find(image, "|%s*thumb%s*[|%]]") or mw.ustring.find(image, "|%s*thumbnail%s*[|%]]")) then
return image --.. "[[Категория:Страницы с миниатюрами в карточках]]";
else
return image;
end
elseif mw.ustring.sub(image,1,2) == "{{" and mw.ustring.sub(image,1,3) ~= "{{{" then
return image;
elseif mw.ustring.sub(image,1,1) == "<" then
return image;
elseif mw.ustring.sub(image,1,5) == mw.ustring.char(127).."UNIQ" then
-- Found strip marker at begining, so pass don't process at all
return image;
else
local result = "";
local size = frame.args["size"];
local maxsize = frame.args["maxsize"];
local sizedefault = frame.args["sizedefault"];
local alt = frame.args["alt"];
local title = frame.args["title"];
local border = yesno(frame.args["border"]);
local upright = frame.args["upright"] or "";
local center = yesno(frame.args["center"]);
local caption = frame.args["caption"];
-- remove file: or image: prefix if exists
if mw.ustring.lower(mw.ustring.sub(image,1,5)) == "file:" then
image = mw.ustring.sub(image,6);
end
if mw.ustring.lower(mw.ustring.sub(image,1,6)) == "image:" then
image = mw.ustring.sub(image,7);
end
if maxsize ~= "" and maxsize ~= nil then
-- if no sizedefault then set to maxsize
if sizedefault == "" or sizedefault == nil then
sizedefault = maxsize
end
-- check to see if size bigger than maxsize
if size ~= "" and size ~= nil then
local sizenumber = tonumber(mw.ustring.match(size,"%d*")) or 0;
local maxsizenumber = tonumber(mw.ustring.match(maxsize,"%d*"));
if sizenumber>maxsizenumber and maxsizenumber>0 then
size = maxsize;
end
end
end
-- add px to size if just a number
if (tonumber(size) or 0) > 0 then
size = size .. "px";
end
result = "[[File:" .. image;
if size ~= "" and size ~= nil then
result = result .. "|" .. size;
elseif sizedefault ~= "" and sizedefault ~= nil then
result = result .. "|" .. sizedefault;
else
result = result .. "|frameless";
end
if center then
result = result .. "|center"
end
if alt ~= "" and alt ~= nil then
result = result .. "|alt=" .. alt;
end
if border then
result = result .. "|border";
end
if upright ~= "" then
result = result .. "|upright=" .. upright;
end
if title ~= "" and title ~= nil then
result = result .. "|" .. title;
elseif alt ~= "" and alt ~= nil then
result = result .. "|" .. alt;
end
result = result .. "]]";
if caption ~= "" and caption ~= nil then
result = result .. '<span class="media-caption" style="display:block">' .. caption .. '</span>';
end
return result;
end
end
return i;
ec0754cf3050a84a661c48656d091d291822e37d
Модуль:Ifempty
828
85
145
144
2024-08-09T17:13:23Z
Ксеноморф
2
1 версия импортирована: Импортировано из Русской Википедии
Scribunto
text/plain
local p = {}
local getArgs = require('Module:Arguments').getArgs
function p.main(frame)
local args = getArgs(frame, {removeBlanks = false})
local before = args['до']
local after = args['после']
for i, v in ipairs(args) do
if v ~= '' then
return (before or '') .. v .. (after or '')
end
end
end
return p
875e8c9f03fb4cc02d80271ad3aaab13a9bcea86
Модуль:Check for unknown parameters
828
86
147
146
2024-08-09T17:13:50Z
Ксеноморф
2
1 версия импортирована: Импортировано из Русской Википедии
Scribunto
text/plain
-- This module may be used to compare the arguments passed to the parent
-- with a list of arguments, returning a specified result if an argument is
-- not on the list
local p = {}
local function trim(s)
return s:match('^%s*(.-)%s*$')
end
local function isnotempty(s)
return s and trim(s) ~= ''
end
function p.check (frame)
local args = frame.args
local pargs = frame:getParent().args
local ignoreblank = isnotempty(frame.args['ignoreblank'])
local showblankpos = isnotempty(frame.args['showblankpositional'])
local knownargs = {}
local unknown = frame.args['unknown'] or 'Found _VALUE_, '
local preview = frame.args['preview']
local values = {}
local res = {}
local regexps = {}
-- create the list of known args, regular expressions, and the return string
for k, v in pairs(args) do
if type(k) == 'number' then
v = trim(v)
knownargs[v] = 1
elseif k:find('^regexp[1-9][0-9]*$') then
table.insert(regexps, '^' .. v .. '$')
end
end
if isnotempty(preview) then
preview = '<div class="hatnote" style="color:red"><strong>Предупреждение:</strong> ' .. preview .. ' (это сообщение видно только при предпросмотре страницы).</div>'
elseif preview == nil then
preview = unknown
end
-- loop over the parent args, and make sure they are on the list
for k, v in pairs(pargs) do
if type(k) == 'string' and knownargs[k] == nil then
local knownflag = false
for i, regexp in ipairs(regexps) do
if mw.ustring.match(k, regexp) then
knownflag = true
break
end
end
if not knownflag and ( not ignoreblank or isnotempty(v) ) then
k = mw.ustring.gsub(k, '[^%w\-_ ]', '?')
table.insert(values, k)
end
elseif type(k) == 'number' and
knownargs[tostring(k)] == nil and
( showblankpos or isnotempty(v) )
then
local vlen = mw.ustring.len(v)
v = mw.ustring.sub(v, 1, (vlen < 25) and vlen or 25)
v = mw.ustring.gsub(v, '[^%w\-_ ]', '?')
table.insert(values, k .. ' = ' .. v .. ((vlen >= 25) and ' ...' or ''))
end
end
-- add resuls to the output tables
if #values > 0 then
if frame:preprocess( "{{REVISIONID}}" ) == "" then
unknown = preview
end
for k, v in pairs(values) do
if v == '' then
-- Fix odd bug for | = which gets stripped to the empty string and
-- breaks category links
v = ' '
end
local r = unknown:gsub('_VALUE_', v)
table.insert(res, r)
end
end
return table.concat(res)
end
function p.generate (frame)
local res = '{{#invoke:check for unknown parameters|check\n' ..
'|unknown=' .. frame.args['unknown'] .. '\n'
local checkerparams = {'ignoreblank', 'preview', 'showblankpositional'}
for _, v in pairs(checkerparams) do
if frame.args[v] then
res = res .. '|' .. v .. '=' .. frame.args[v] .. '\n'
end
end
local templatenamespace = frame.args[1]
local templatetitle = frame.args[2]
local pagepointer = mw.title.new(templatetitle, templatenamespace) -- именно такой порядок!
local text = pagepointer.getContent(pagepointer)
local params = {}
for param in string.gmatch(text, '\{\{\{([^\|\}]*)') do
params[#params+1] = mw.text.trim(param)
end
table.sort(params)
for k, v in pairs(params) do
if k == 1 or v ~= params[k-1] then
res = res .. '|' .. v
end
end
res = res .. '}}'
return res
end
return p
718ece7132a40acc051a3da4cdf668a76c02d10d
Модуль:Navbar
828
87
149
148
2024-08-09T17:14:41Z
Ксеноморф
2
1 версия импортирована: Импортировано из Русской Википедии
Scribunto
text/plain
local p = {}
local hlist = 'Template:Flatlist/styles.css'
local templatestyles = 'Module:Navbar/styles.css'
local getArgs
function p._ruwikiNavbar( args )
local titleText = args[ 1 ] or (':' .. mw.getCurrentFrame():getParent():getTitle())
local title = mw.title.new(mw.text.trim(titleText), 'Template');
if not title then
error('Invalid title ' .. titleText)
end
local whiteColorDefs = {
['#fff'] = true,
['#ffffff'] = true,
['white'] = true,
}
local fontColor = args.fontcolor and args.fontcolor:lower()
local isWhite = fontColor and whiteColorDefs[ fontColor ] == true
local fontStyle = args.fontstyle and mw.text.unstripNoWiki( args.fontstyle:lower() )
if not isWhite and fontStyle then
local styleratio = require( 'Module:Color contrast' )._styleratio
isWhite = styleratio( {
fontStyle .. '; color:#666;',
'',
'#666'
} ) < 3.66
end
local isTemplate = title.namespace == 10
local altText = string.format(
'Перейти %s «%s»',
isTemplate and 'к шаблону' or 'на страницу',
mw.text.split( isTemplate and title.text or title.fullText, '#' )[ 1 ]
)
return string.format(
'[[Файл:Wikipedia interwiki section gear icon%s.svg|14px|class=noprint%s|link=%s|%s]]',
isWhite and ' white' or '',
isWhite and '' or ' skin-invert-image',
tostring( title ),
altText
)
end
function p.ruwikiNavbar(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
return p._ruwikiNavbar(getArgs(frame))
end
function p._navbar(args)
local titleArg = 1
if args.collapsible then
titleArg = 2
if not args.plain then
args.mini = 1
end
if args.fontcolor then
args.fontstyle = 'color:' .. args.fontcolor .. ';'
end
args.style = 'float:left; text-align:left; white-space:nowrap;'
end
if args[titleArg] == 'off' then
return
end
local titleText = args[titleArg] or (':' .. mw.getCurrentFrame():getParent():getTitle())
local title = mw.title.new(mw.text.trim(titleText), 'Template');
if not title then
error('Invalid title ' .. titleText)
end
local talkpage = title.talkPageTitle and title.talkPageTitle.fullText or '';
local tag
if args.nodiv then
tag = 'span'
else
tag = 'div'
end
local div = mw.html.create():tag(tag)
div
:addClass('navbar hlist plainlinks noprint')
:attr('data-navboxnavigation-link', '0')
:cssText(args.style)
if args.mini then div:addClass('navbar-mini') end
if not (args.mini or args.plain) then
div
:tag('span')
:addClass('navbar-boxtext')
:cssText(args.fontstyle)
:wikitext(args.text or 'Шаблон:')
:wikitext(' ')
end
local ul = div:tag('ul');
if args.brackets then
ul:addClass('navbar-brackets')
end
ul
:tag('li')
:addClass('nv-view')
:wikitext('[[' .. title.fullText .. '|')
:tag(args.mini and 'abbr' or 'span')
:addClass(args.mini and 'navbar-mini-abbr')
:attr('title', 'Просмотр этого шаблона')
:cssText(args.fontstyle)
:wikitext(args.mini and 'п' or 'просмотр')
:done()
:wikitext(']]')
:done()
:tag('li')
:addClass('nv-talk')
:wikitext('[[' .. talkpage .. '|')
:tag(args.mini and 'abbr' or 'span')
:attr('title', 'Обсуждение этого шаблона')
:cssText(args.fontstyle)
:wikitext(args.mini and 'о' or 'обсуждение')
:done()
:wikitext(']]');
if not args.noedit then
ul
:tag('li')
:addClass('nv-edit')
:wikitext('[[Special:EditPage/' .. title.fullText .. '|')
:tag(args.mini and 'abbr' or 'span')
:attr('title', 'Править этот шаблон')
:cssText(args.fontstyle)
:wikitext(args.mini and 'р' or 'править')
:done()
:wikitext(']]');
end
if args.collapsible then
div:done()
:tag('span')
:addClass( args.mini and 'navbar-ct-mini' or 'navbar-ct-full' )
:cssText(args.fontstyle)
:wikitext(args[1])
end
local frame = mw.getCurrentFrame()
return frame:extensionTag{
name = 'templatestyles', args = { src = hlist }
} .. frame:extensionTag{
name = 'templatestyles', args = { src = templatestyles }
} .. tostring(div:done())
end
function p.navbar(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
return p._navbar(getArgs(frame))
end
return p
695777e4dafbd5f7bf8b4f35d8db9349d08a363d
Файл:Флаг Ксеноморфии.svg
6
88
150
2024-08-09T17:18:44Z
Ксеноморф
2
wikitext
text/x-wiki
da39a3ee5e6b4b0d3255bfef95601890afd80709
152
150
2024-08-09T17:21:12Z
DuOfOrl
5
DuOfOrl переименовал страницу [[Файл:Flag of Xenomorphia (1).svg]] в [[Файл:Флаг Ксеноморфии.svg]] без оставления перенаправления: Название с ошибкой
wikitext
text/x-wiki
da39a3ee5e6b4b0d3255bfef95601890afd80709
Файл:Coat of Arms of Xenomorphian Republic.png
6
89
151
2024-08-09T17:19:48Z
Ксеноморф
2
wikitext
text/x-wiki
da39a3ee5e6b4b0d3255bfef95601890afd80709
Файл:Flag of the President of Xenomorphia.png
6
90
153
2024-08-09T17:21:14Z
Ксеноморф
2
wikitext
text/x-wiki
da39a3ee5e6b4b0d3255bfef95601890afd80709
Модуль:Wikibase
828
92
157
156
2024-08-09T20:38:29Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
-- Модуль для функционала Викиданных
local M = {};
local function tabletostr( t, fmt, s, o, c ) -- не для использования на страницах
if type( t ) == "table" then
local f = {};
for k, v in pairs( t ) do
table.insert( f, string.format( fmt or '%s = %s', k, tabletostr( v, fmt, s, o, c ) ) )
end;
table.sort( f );
return ( o or '' ) .. table.concat( f, s or '' ) .. ( c or '' )
else
return tostring( t )
end
end
function M.wbview( ref, id ) -- вспом. функция для подписи из Викиданных
local l = mw.wikibase.label( id );
return l and ( l == ref and l or ref .. '|' .. l .. ( mw.ustring.lower( l ) == mw.ustring.lower( ref ) and '' or '<sup>*</sup>' ) ) or ref
end
function M.id( frame ) -- Элемент текущей страницы в Викиданных
--Если вызван с параметром, достаёт id значения данного свойства, иначе возвращает id страницы
--Второй параметр - разделитель, если значений несколько ("; " по умолчанию),
-- либо можно указать номер параметром n. Третий параметр - формат для строкового свойства,
-- по умолчанию "%s"
local function try()
local e = mw.wikibase.getEntity();
if frame.args[ 1 ] then
local function gv( i )
local z = e.claims[ frame.args[ 1 ] ][ i ].mainsnak.datavalue;
if z.type == 'wikibase-entityid' then
return z.value.id
else
return string.format( frame.args[ 3 ] or '%s', tabletostr( z.value, "%s", '; ', '{', '}' ) )
end
end
if frame.args[ 'n' ] then
return gv( tonumber( frame.args[ 'n' ] ) )
end
local p, h = e.claims[ frame.args[ 1 ] ], {}
for n, v in pairs( p ) do
h[ n ] = gv( n )
end
return table.concat( h, frame.args[ 2 ] or "; " )
else
return e.id
end
end
local r, result = pcall( try );
if r then
return result;
else
return '<strong class="error">В Викиданных нет записей для текущей страницы</strong>';
end
end
function M.struc( frame ) -- Отладочная функция, будет перенесена в отдельный модуль
--Структуру см. [[mw:Extension:WikibaseClient/Lua#Entity table and data structure]]
local function try()
local i, e = 1, mw.wikibase.getEntity();
while frame.args[i] do
e = e[ frame.args[ i ] ] or e[ tonumber( frame.args[ i ] ) ];
i = i + 1
end
return tabletostr( e, frame.args[ 'f' ], frame.args[ 's' ] or '; ', '{', '}' )
end
local r, result = pcall( try );
if r then
return result;
else
return '<strong class="error">В Викиданных нет записей для текущей страницы</strong>';
end
end
function M.label( frame ) -- Комментарий к элементу Викиданных в 1-м параметре
local function try()
local id = frame.args[1];
if not id or id == '' then
id = mw.wikibase.getEntityIdForCurrentPage(); -- error, если нет элемента
end
return mw.wikibase.label( id );
end
local r, result = pcall( try );
if r then
return result;
else
return '<strong class="error">В Викиданных нет записей для текущей страницы</strong>';
end
end
function M.description( frame )
local function try()
local entityId = frame.args[1];
if not entityId or entityId == '' then
entityId = mw.wikibase.getEntityIdForCurrentPage(); -- error, если нет элемента
end
return mw.wikibase.description( entityId )
end
local r, result = pcall( try );
if r then
return result;
else
return '<strong class="error">В Викиданных нет записей для указанной страницы</strong>';
end
end
function M.iwiki( frame ) -- Интервики для указанного языка (только с ВД)
local function try()
if frame.args[ 1 ] then
return mw.wikibase.getEntity().sitelinks[ frame.args[ 1 ] .. 'wiki' ].title
else-- список интервик
local r = {};
for k, v in pairs( mw.wikibase.getEntity().sitelinks ) do
table.insert( r, string.format( frame.args[ 'f' ] or "* [[:%s:%s]]\n", v.language, v.title ) )
end
return table.concat( r )
end
end
local r, result = pcall( try );
if r then
return result;
else
return '<strong class="error">В Викиданных нет записей для текущей страницы</strong>';
end
end
function M.iwikiall( frame ) -- Все ссылки, привязанные к элементу на ВД, в т.ч. викигид и склад
local function try()
if frame.args[ 1 ] then
return mw.wikibase.getEntity().sitelinks[ frame.args[ 1 ] ].title
else-- список интервик
local r = {};
for k, v in pairs( mw.wikibase.getEntity().sitelinks ) do
table.insert( r, string.format( frame.args[ 'f' ] or "* [[:%s:%s]]\n", v.language, v.title ) )
end
return table.concat(r)
end
end
local r, result = pcall( try );
if r then
return result;
else
return '';
end
end
function M.page( frame ) -- страница Рувики для данного элемента
local function try()
return mw.wikibase.sitelink( frame.args[ 1 ] )
end
local r, result = pcall( try );
if r then
return result;
else
return '<strong class="error">В Викиданных нет записей для текущей страницы</strong>';
end
end
function M.wdprops( frame ) -- список всех свойств с ВД в человеко-читаемом виде
local function try()
local e, r = mw.wikibase.getEntity(), {};
for p, a in pairs( e.claims ) do
local label = mw.wikibase.label( p ) or string.format( [[d:%s]], p );
local vals = {};
for n, v in pairs( a ) do
local w = v.mainsnak.datavalue;
vals[ n ] = (
w.type == 'wikibase-entityid'
and '[[' .. M.wbview(
mw.wikibase.sitelink( w.value.id )
or 'd:' .. w.value.id,
w.value.id
) .. ']]' or M.tabletostr( w.value )
)
end
table.insert( r, string.format(
frame.args[ 'f' ] or '\n|-\n|rowspan=%i|%s\n|%s',
#vals,
label,
table.concat( vals, frame.args[ 's' ] or '\n|-\n|' )
) )
end--for
return table.concat( r )
end
local r, result = pcall( try );
if r then
return result;
else
return '<strong class="error">В Викиданных нет записей для текущей страницы</strong>';
end
end
return M
fc7c167bb9ef635b35a685123b273c486c229190
Шаблон:Рейтинг модуля
10
93
159
158
2024-08-09T20:43:36Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{Module other|{{ombox
| type = notice
| image = {{#switch: {{{1|}}}
| pre-alpha | prealpha | pa | пре-альфа = [[File:Ambox warning blue construction.svg|40x40px|link=]]
| alpha | a | альфа = [[File:Greek lc alpha icon.svg|26x26px|link=|class=skin-invert-image]]
| beta | b | бета = [[File:Greek lc beta icon.svg|40x40px|link=|class=skin-invert-image]]
| release | r | general | g | готов = [[File:Green check.svg|40x40px|link=]]
| protected | protect | p | защищен = [[File:Padlock-silver.svg|40x40px|link=]]
}}
| style =
| textstyle =
| text = {{#switch: {{{1|}}}
| pre-alpha | prealpha | pa | пре-альфа = Этот модуль оценён как [[:Категория:Модули:Пре-альфа версии|пре-альфа-версия]]. Он не закончен и может находиться в разработке. Он не должен использоваться в статьях. Модули остаются в этой стадии до тех пор, пока автор или кто-либо иной не сочтёт их структуру удовлетворительной.<!--
-->{{#switch: {{SUBPAGENAME}}|doc|sandbox=<!-- No category for /doc or /sandbox subpages -->
| {{#ifeq: {{{nocat|}}} | true | <!-- No category if user sets nocat=true --> | [[Категория:Модули:Пре-альфа версии]] }}
}}
| alpha | a | альфа = Этот модуль оценён как [[:Категория:Модули:Альфа-версии|альфа-версия]]. Он готов для тестирований и может быть использован на небольшом количестве страниц для обнаружения проблем. Предложения по изменениям и дополнениям приветствуются.<!--
-->{{#switch: {{SUBPAGENAME}}|doc|sandbox=<!-- No category for /doc or /sandbox subpages -->
| {{#ifeq: {{{nocat|}}} | true | <!-- No category if user sets nocat=true --> | [[Категория:Модули:Альфа-версии]] }}
}}
| beta | b | бета = Этот модуль оценён как [[:Категория:Модули:Бета-версии|бета-версия]]. Он готов для широкого применения, но должен применяться с осторожностью.<!--
-->{{#switch: {{SUBPAGENAME}}|doc|sandbox=<!-- No category for /doc or /sandbox subpages -->
| {{#ifeq: {{{nocat|}}} | true | <!-- No category if user sets nocat=true --> | [[Категория:Модули:Бета-версии]] }}
}}
| release | r | general | g | готов = Этот модуль оценён как [[:Категория:Модули:Стабильные|готовый к использованию]]. Предполагается, что все баги устранены и он готов для широкого использования. Его можно указывать на справочных страницах и рекомендовать к использованию новым участникам. Для его изменения и тестирования, пожалуйста, [[ВП:ТЕСТЫ|используйте песочницу]].<!--
-->{{#switch: {{SUBPAGENAME}}|doc|sandbox=<!-- No category for /doc or /sandbox subpages -->
| {{#ifeq: {{{nocat|}}} | true | <!-- No category if user sets nocat=true --> | [[Категория:Модули:Стабильные]] }}
}}
| protected | protect | p | защищен = Этот модуль относится к [[:Категория:Модули:Критические|критическим]]. У него очень много включений или он используется с подстановкой. Из-за опасности вандализма или ошибочного редактирования он был защищён.<!--
-->{{#switch: {{SUBPAGENAME}}|doc|sandbox=<!-- No category for /doc or /sandbox subpages -->
| {{#ifeq: {{{nocat|}}} | true | <!-- No category if user sets nocat=true --> | [[Категория:Модули:Критические]] }}
}}
| #default = {{error|Рейтинг не указан или указан неправильно.}}
}}
}}|{{error|Этот шаблон должен использоваться в пространстве модулей.}}|demospace={{{demospace|<noinclude>module</noinclude>}}}}}<noinclude>{{doc}}</noinclude>
c3380f20f70295631f2614caead4cbc73c110883
Шаблон:Module rating
10
94
160
2024-08-09T20:47:22Z
DuOfOrl
5
Перенаправление на [[Шаблон:Рейтинг модуля]]
wikitext
text/x-wiki
#REDIRECT [[Шаблон:Рейтинг модуля]]
4fffdbbfc33a362b03306003030f85ea1a516c19
Шаблон:Module other
10
95
162
161
2024-08-09T20:49:33Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{#switch:
<!--If no or empty "demospace" parameter then detect namespace-->
{{#if:{{{demospace|}}}
| {{lc: {{{demospace}}} }} <!--Use lower case "demospace"-->
| {{#ifeq:{{NAMESPACE}}|{{ns:Module}}
| module
| other
}}
}}
| module = {{{1|}}}
| other
| #default = {{{2|}}}
}}<!--End switch--><noinclude>
{{doc}}
<!-- Add categories and interwikis to the /doc subpage, not here! -->
</noinclude>
097d5ea3648fcbbe0ccd87e8f217c713e97922c7
Международный аэропорт им.Азадырова Жщинькарху
0
96
163
2024-08-10T08:25:32Z
Ксеноморф
2
Новая страница: «'''Международный аэропорт имени Азадырова Жщинькарху (код ИКАО: XLAH; код ИАТА: XAH)''' — второй и самый крупный аэропорт [[Ксеноморфленда]], а также крупнейший аэропорт в стране. Аэропорт был сдан в эксплуатацию в 2022 году и с тех пор стал важным узлом для между...»
wikitext
text/x-wiki
'''Международный аэропорт имени Азадырова Жщинькарху (код ИКАО: XLAH; код ИАТА: XAH)''' — второй и самый крупный аэропорт [[Ксеноморфленда]], а также крупнейший аэропорт в стране. Аэропорт был сдан в эксплуатацию в 2022 году и с тех пор стал важным узлом для международного авиасообщения, обеспечивая связь Ксеноморфленда с различными направлениями по всему миру.
== Общая информация ==
Аэропорт расположен в пригороде Жщинькарху, в 10 километрах от центра города. Это обеспечивает удобный доступ для пассажиров как на наземном транспорте, так и на такси.
== Инфраструктура ==
Аэропорт им. Азадырова предлагает широкий спектр услуг для пассажиров, включая современные комфортабельные залы ожидания, кафе, рестораны, магазины беспошлинной торговли, а также услуги аренды автомобилей. В аэропорту работают представительства многих ксеноморфических авиакомпаний, а также информационные пункты, где пассажиры могут получить необходимую информацию.
== Транспортные сообщения ==
Транспортное сообщение между аэропортом и городом хорошо организовано, что делает его доступным и удобным для пассажиров. Пользуясь автобусами и электропоездами, путешественники могут быстро и легко добраться до международного аэропорта им.Азадырова Жщинькарху из различных частей города.
=== Автобусное Движение ===
Международный аэропорт имени Азадырова Жщинькарху связан с городом с помощью пяти экспресс-маршрутов:
- E673: [[Железнодорожный вокзал]] - Аэропорт
- E882: [[Деловой центр]] - Аэропорт
- E989: [[Район Эвервинд]] - Аэропорт
- E1000: [[Пригородный вокзал]] - Аэропорт
- E9813: [[Новберг]] - Аэропорт
Автобусы на этих маршрутах следуют с минимальным количеством остановок и обеспечивают высокую скорость передвижения. Основными автомобилями, обслуживающими маршруты, являются [["MAN Lions City"]], за исключением маршрута E9813, который обслуживается автобусами [["MAN Lions Regio"]].
=== Электропоезда ===
'''Станция "Международный аэропорт имени Азадырова Жщинькарху"''' была открыта 1 января 2022 года и является тупиковой станцией на отдельной ветке. Аэроэкспрессы обслуживают скоростные электропоезда, которые могут разгоняться до 120 км/ч. Поезда курсируют от пригородного вокзала и делают три остановки до аэропорта, что позволяет добраться до места назначения за 20 минут. Электричка ходит каждый час, обеспечивая комфортное и быстрое соединение с городом.
83839160a17b123981f9947d36acc7fe77774b71
164
163
2024-08-10T08:26:02Z
Ксеноморф
2
wikitext
text/x-wiki
'''Международный аэропорт имени Азадырова Жщинькарху (код ИКАО: XLAH; код ИАТА: XAH)''' — второй и самый крупный аэропорт [[Ксеноморфленда]], а также крупнейший аэропорт в стране. Аэропорт был сдан в эксплуатацию в 2022 году и с тех пор стал важным узлом для международного авиасообщения, обеспечивая связь Ксеноморфленда с различными направлениями по всему миру.
== Общая информация ==
Аэропорт расположен в пригороде Жщинькарху, в 10 километрах от центра города. Это обеспечивает удобный доступ для пассажиров как на наземном транспорте, так и на такси.
== Инфраструктура ==
Аэропорт им. Азадырова предлагает широкий спектр услуг для пассажиров, включая современные комфортабельные залы ожидания, кафе, рестораны, магазины беспошлинной торговли, а также услуги аренды автомобилей. В аэропорту работают представительства многих ксеноморфических авиакомпаний, а также информационные пункты, где пассажиры могут получить необходимую информацию.
== Транспортные сообщения ==
Транспортное сообщение между аэропортом и городом хорошо организовано, что делает его доступным и удобным для пассажиров. Пользуясь автобусами и электропоездами, путешественники могут быстро и легко добраться до международного аэропорта им.Азадырова Жщинькарху из различных частей города.
=== Автобусное Движение ===
Международный аэропорт имени Азадырова Жщинькарху связан с городом с помощью пяти экспресс-маршрутов:
- E673: [[Железнодорожный вокзал]] - Аэропорт
- E882: [[Деловой центр]] - Аэропорт
- E989: [[Район Эвервинд]] - Аэропорт
- E1000: [[Пригородный вокзал]] - Аэропорт
- E9813: [[Новберг]] - Аэропорт
Автобусы на этих маршрутах следуют с минимальным количеством остановок и обеспечивают высокую скорость передвижения. Основными автомобилями, обслуживающими маршруты, являются [["MAN Lions City"]], за исключением маршрута E9813, который обслуживается автобусами [["MAN Lions Regio"]].
=== Электропоезда ===
'''Станция "Международный аэропорт имени Азадырова Жщинькарху"''' была открыта 1 января 2022 года и является тупиковой станцией на отдельной ветке. Аэроэкспрессы обслуживают скоростные электропоезда, которые могут разгоняться до 120 км/ч. Поезда курсируют от пригородного вокзала и делают три остановки до аэропорта, что позволяет добраться до места назначения за 20 минут. Электричка ходит каждый час, обеспечивая комфортное и быстрое соединение с городом.
18d7ab6499118ffd4f3dc5fae1d2f6041c282598
165
164
2024-08-10T08:29:32Z
Ксеноморф
2
wikitext
text/x-wiki
'''Международный аэропорт имени Азадырова Жщинькарху (код ИКАО: XLAH; код ИАТА: XAH)''' — второй и самый крупный аэропорт [[Ксеноморфленда]], а также крупнейший аэропорт в [[Ксеноморфии]. Аэропорт был сдан в эксплуатацию в 2022 году и с тех пор стал важным узлом для международного авиасообщения, обеспечивая связь Ксеноморфленда с различными направлениями по всему миру.
== Общая информация ==
Аэропорт расположен в пригороде Жщинькарху, в 10 километрах от центра города. Это обеспечивает удобный доступ для пассажиров как на наземном транспорте, так и на такси.
== Инфраструктура ==
Аэропорт им. Азадырова предлагает широкий спектр услуг для пассажиров, включая современные комфортабельные залы ожидания, кафе, рестораны, магазины беспошлинной торговли, а также услуги аренды автомобилей. В аэропорту работают представительства многих ксеноморфических авиакомпаний, а также информационные пункты, где пассажиры могут получить необходимую информацию.
== Транспортные сообщения ==
Транспортное сообщение между аэропортом и городом хорошо организовано, что делает его доступным и удобным для пассажиров. Пользуясь автобусами и электропоездами, путешественники могут быстро и легко добраться до международного аэропорта им.Азадырова Жщинькарху из различных частей города.
=== Автобусное Движение ===
Международный аэропорт имени Азадырова Жщинькарху связан с городом с помощью пяти экспресс-маршрутов:
- E673: [[Железнодорожный вокзал]] - Аэропорт
- E882: [[Деловой центр]] - Аэропорт
- E989: [[Район Эвервинд]] - Аэропорт
- E1000: [[Пригородный вокзал]] - Аэропорт
- E9813: [[Новберг]] - Аэропорт
Автобусы на этих маршрутах следуют с минимальным количеством остановок и обеспечивают высокую скорость передвижения. Основными автомобилями, обслуживающими маршруты, являются [["MAN Lions City"]], за исключением маршрута E9813, который обслуживается автобусами [["MAN Lions Regio"]].
=== Электропоезда ===
'''Станция "Международный аэропорт имени Азадырова Жщинькарху"''' была открыта 1 января 2022 года и является тупиковой станцией на отдельной ветке. Аэроэкспрессы обслуживают скоростные электропоезда, которые могут разгоняться до 120 км/ч. Поезда курсируют от пригородного вокзала и делают три остановки до аэропорта, что позволяет добраться до места назначения за 20 минут. Электричка ходит каждый час, обеспечивая комфортное и быстрое соединение с городом.
487d34efc9243a942feb9d63232943ec99612ab5
166
165
2024-08-10T08:36:02Z
Ксеноморф
2
wikitext
text/x-wiki
'''Международный аэропорт имени Азадырова Жщинькарху (код ИКАО: XLAH; код ИАТА: XAH)''' — второй и самый крупный аэропорт [[Ксеноморфленда]], а также крупнейший аэропорт в [[Ксеноморфии]. Аэропорт был сдан в эксплуатацию в 2022 году и с тех пор стал важным узлом для международного авиасообщения, обеспечивая связь Ксеноморфленда с различными направлениями по всему миру. Аэропорт расположен в пригороде Жщинькарху, в 10 километрах от центра города. Это обеспечивает удобный доступ для пассажиров как на наземном транспорте, так и на такси.
Аэропорт служит хабом для авиакомпании [[Xenomorphiland Caeli]], а также является одним из главных аэропортов для [[Xenomorphia Airlines]] и [[Povaria Airlines]]. Местное население часто называет его XLAH — по его коду ICAO.
== Инфраструктура ==
Аэропорт им. Азадырова предлагает широкий спектр услуг для пассажиров, включая современные комфортабельные залы ожидания, кафе, рестораны, магазины беспошлинной торговли, а также услуги аренды автомобилей. В аэропорту работают представительства многих ксеноморфических авиакомпаний, а также информационные пункты, где пассажиры могут получить необходимую информацию.
== Транспортные сообщения ==
Транспортное сообщение между аэропортом и городом хорошо организовано, что делает его доступным и удобным для пассажиров. Пользуясь автобусами и электропоездами, путешественники могут быстро и легко добраться до международного аэропорта им.Азадырова Жщинькарху из различных частей города.
=== Автобусное Движение ===
Международный аэропорт имени Азадырова Жщинькарху связан с городом с помощью пяти экспресс-маршрутов:
- E673: [[Железнодорожный вокзал]] - Аэропорт
- E882: [[Деловой центр]] - Аэропорт
- E989: [[Район Эвервинд]] - Аэропорт
- E1000: [[Пригородный вокзал]] - Аэропорт
- E9813: [[Новберг]] - Аэропорт
Автобусы на этих маршрутах следуют с минимальным количеством остановок и обеспечивают высокую скорость передвижения. Основными автомобилями, обслуживающими маршруты, являются [https://ru.wikipedia.org/wiki/MAN_Lion%E2%80%99s_City/ "MAN Lions City"], за исключением маршрута E9813, который обслуживается автобусами [https://ru.wikipedia.org/wiki/MAN_Lion%E2%80%99s_Regio/ "MAN Lions Regio"].
=== Электропоезда ===
'''Станция "Международный аэропорт имени Азадырова Жщинькарху"''' была открыта 1 января 2022 года и является тупиковой станцией на отдельной ветке. Аэроэкспрессы обслуживают скоростные электропоезда, которые могут разгоняться до 120 км/ч. Поезда курсируют от пригородного вокзала и делают три остановки до аэропорта, что позволяет добраться до места назначения за 20 минут. Электричка ходит каждый час, обеспечивая комфортное и быстрое соединение с городом.
0bffe43720d425625c7c81af9e5dbfee66487c4b
167
166
2024-08-10T08:36:50Z
Ксеноморф
2
wikitext
text/x-wiki
'''Международный аэропорт имени Азадырова Жщинькарху (код ИКАО: XLAH; код ИАТА: XAH)''' — второй и самый крупный аэропорт [[Ксеноморфленда]], а также крупнейший аэропорт в [[Ксеноморфии]. Аэропорт был сдан в эксплуатацию в 2022 году и с тех пор стал важным узлом для международного авиасообщения, обеспечивая связь Ксеноморфленда с различными направлениями по всему миру. Аэропорт расположен в пригороде Жщинькарху, в 10 километрах от центра города. Это обеспечивает удобный доступ для пассажиров как на наземном транспорте, так и на такси.
Аэропорт служит хабом для авиакомпании [[Xenomorphiland Caeli]], а также является одним из главных аэропортов для [[Xenomorphia Airlines]] и [[Povaria Airlines]]. Местное население часто называет его XLAH — по его коду ICAO.
== Инфраструктура ==
Аэропорт им. Азадырова предлагает широкий спектр услуг для пассажиров, включая современные комфортабельные залы ожидания, кафе, рестораны, магазины беспошлинной торговли, а также услуги аренды автомобилей. В аэропорту работают представительства многих ксеноморфических авиакомпаний, а также информационные пункты, где пассажиры могут получить необходимую информацию.
== Транспортные сообщения ==
Транспортное сообщение между аэропортом и городом хорошо организовано, что делает его доступным и удобным для пассажиров. Пользуясь автобусами и электропоездами, путешественники могут быстро и легко добраться до международного аэропорта им.Азадырова Жщинькарху из различных частей города.
=== Автобусное Движение ===
Международный аэропорт имени Азадырова Жщинькарху связан с городом с помощью пяти экспресс-маршрутов:
- E673: [[Железнодорожный вокзал]] - Аэропорт
- E882: [[Деловой центр]] - Аэропорт
- E989: [[Район Эвервинд]] - Аэропорт
- E1000: [[Пригородный вокзал]] - Аэропорт
- E9813: [[Новберг]] - Аэропорт
Автобусы на этих маршрутах следуют с минимальным количеством остановок и обеспечивают высокую скорость передвижения. Основными автомобилями, обслуживающими маршруты, являются [https://ru.wikipedia.org/wiki/MAN_Lion%E2%80%99s_City "MAN Lions City"], за исключением маршрута E9813, который обслуживается автобусами [https://ru.wikipedia.org/wiki/MAN_Lion%E2%80%99s_Regio "MAN Lions Regio"].
=== Электропоезда ===
'''Станция "Международный аэропорт имени Азадырова Жщинькарху"''' была открыта 1 января 2022 года и является тупиковой станцией на отдельной ветке. Аэроэкспрессы обслуживают скоростные электропоезда, которые могут разгоняться до 120 км/ч. Поезда курсируют от пригородного вокзала и делают три остановки до аэропорта, что позволяет добраться до места назначения за 20 минут. Электричка ходит каждый час, обеспечивая комфортное и быстрое соединение с городом.
5bca896b84f351a4cc03d85e16e7d862f669456f
170
167
2024-08-10T08:47:29Z
Ксеноморф
2
wikitext
text/x-wiki
'''Международный аэропорт имени Азадырова Жщинькарху (код ИКАО: XLAH; код ИАТА: XAH)''' — второй и самый крупный аэропорт [[Ксеноморфленда|https://memnotation.miraheze.org/wiki/%D0%9A%D1%81%D0%B5%D0%BD%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%BB%D0%B5%D0%BD%D0%B4]], а также крупнейший аэропорт в [[Ксеноморфии]]. Аэропорт был сдан в эксплуатацию в 2022 году и с тех пор стал важным узлом для международного авиасообщения, обеспечивая связь Ксеноморфленда с различными направлениями по всему миру. Аэропорт расположен в пригороде Жщинькарху, в 10 километрах от центра города. Это обеспечивает удобный доступ для пассажиров как на наземном транспорте, так и на такси.
Аэропорт служит хабом для авиакомпании [[Xenomorphiland Caeli]], а также является одним из главных аэропортов для [[Xenomorphia Airlines]] и [[Povaria Airlines]]. Местное население часто называет его XLAH — по его коду ICAO.
== Инфраструктура ==
Аэропорт им. Азадырова предлагает широкий спектр услуг для пассажиров, включая современные комфортабельные залы ожидания, кафе, рестораны, магазины беспошлинной торговли, а также услуги аренды автомобилей. В аэропорту работают представительства многих ксеноморфических авиакомпаний, а также информационные пункты, где пассажиры могут получить необходимую информацию.
== Транспортные сообщения ==
Транспортное сообщение между аэропортом и городом хорошо организовано, что делает его доступным и удобным для пассажиров. Пользуясь автобусами и электропоездами, путешественники могут быстро и легко добраться до международного аэропорта им.Азадырова Жщинькарху из различных частей города.
=== Автобусное Движение ===
Международный аэропорт имени Азадырова Жщинькарху связан с городом с помощью пяти экспресс-маршрутов:
- E673: [[Железнодорожный вокзал]] - Аэропорт
- E882: [[Деловой центр]] - Аэропорт
- E989: [[Район Эвервинд]] - Аэропорт
- E1000: [[Пригородный вокзал]] - Аэропорт
- E9813: [[Новберг]] - Аэропорт
Автобусы на этих маршрутах следуют с минимальным количеством остановок и обеспечивают высокую скорость передвижения. Основными автомобилями, обслуживающими маршруты, являются [https://ru.wikipedia.org/wiki/MAN_Lion%E2%80%99s_City "MAN Lions City"], за исключением маршрута E9813, который обслуживается автобусами [https://ru.wikipedia.org/wiki/MAN_Lion%E2%80%99s_Regio "MAN Lions Regio"].
=== Электропоезда ===
'''Станция "Международный аэропорт имени Азадырова Жщинькарху"''' была открыта 1 января 2022 года и является тупиковой станцией на отдельной ветке. Аэроэкспрессы обслуживают скоростные электропоезда, которые могут разгоняться до 120 км/ч. Поезда курсируют от пригородного вокзала и делают три остановки до аэропорта, что позволяет добраться до места назначения за 20 минут. Электричка ходит каждый час, обеспечивая комфортное и быстрое соединение с городом.
33e093d97f6f6bdff8ea9456c55f499b548b1690
171
170
2024-08-10T08:47:50Z
Ксеноморф
2
wikitext
text/x-wiki
'''Международный аэропорт имени Азадырова Жщинькарху (код ИКАО: XLAH; код ИАТА: XAH)''' — второй и самый крупный аэропорт [[https://memnotation.miraheze.org/wiki/%D0%9A%D1%81%D0%B5%D0%BD%D0%BE%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%BB%D0%B5%D0%BD%D0%B4|Ксеноморфиленда]], а также крупнейший аэропорт в [[Ксеноморфии]]. Аэропорт был сдан в эксплуатацию в 2022 году и с тех пор стал важным узлом для международного авиасообщения, обеспечивая связь Ксеноморфленда с различными направлениями по всему миру. Аэропорт расположен в пригороде Жщинькарху, в 10 километрах от центра города. Это обеспечивает удобный доступ для пассажиров как на наземном транспорте, так и на такси.
Аэропорт служит хабом для авиакомпании [[Xenomorphiland Caeli]], а также является одним из главных аэропортов для [[Xenomorphia Airlines]] и [[Povaria Airlines]]. Местное население часто называет его XLAH — по его коду ICAO.
== Инфраструктура ==
Аэропорт им. Азадырова предлагает широкий спектр услуг для пассажиров, включая современные комфортабельные залы ожидания, кафе, рестораны, магазины беспошлинной торговли, а также услуги аренды автомобилей. В аэропорту работают представительства многих ксеноморфических авиакомпаний, а также информационные пункты, где пассажиры могут получить необходимую информацию.
== Транспортные сообщения ==
Транспортное сообщение между аэропортом и городом хорошо организовано, что делает его доступным и удобным для пассажиров. Пользуясь автобусами и электропоездами, путешественники могут быстро и легко добраться до международного аэропорта им.Азадырова Жщинькарху из различных частей города.
=== Автобусное Движение ===
Международный аэропорт имени Азадырова Жщинькарху связан с городом с помощью пяти экспресс-маршрутов:
- E673: [[Железнодорожный вокзал]] - Аэропорт
- E882: [[Деловой центр]] - Аэропорт
- E989: [[Район Эвервинд]] - Аэропорт
- E1000: [[Пригородный вокзал]] - Аэропорт
- E9813: [[Новберг]] - Аэропорт
Автобусы на этих маршрутах следуют с минимальным количеством остановок и обеспечивают высокую скорость передвижения. Основными автомобилями, обслуживающими маршруты, являются [https://ru.wikipedia.org/wiki/MAN_Lion%E2%80%99s_City "MAN Lions City"], за исключением маршрута E9813, который обслуживается автобусами [https://ru.wikipedia.org/wiki/MAN_Lion%E2%80%99s_Regio "MAN Lions Regio"].
=== Электропоезда ===
'''Станция "Международный аэропорт имени Азадырова Жщинькарху"''' была открыта 1 января 2022 года и является тупиковой станцией на отдельной ветке. Аэроэкспрессы обслуживают скоростные электропоезда, которые могут разгоняться до 120 км/ч. Поезда курсируют от пригородного вокзала и делают три остановки до аэропорта, что позволяет добраться до места назначения за 20 минут. Электричка ходит каждый час, обеспечивая комфортное и быстрое соединение с городом.
51168f65ffda900276d54361c20142f6cc76bdb6
172
171
2024-08-10T08:49:06Z
Ксеноморф
2
wikitext
text/x-wiki
'''Международный аэропорт имени Азадырова Жщинькарху (код ИКАО: XLAH; код ИАТА: XAH)''' — второй и самый крупный аэропорт [[Ксеноморфиленд|Ксеноморфиленда]], а также крупнейший аэропорт в [[Ксеноморфии]]. Аэропорт был сдан в эксплуатацию в 2022 году и с тех пор стал важным узлом для международного авиасообщения, обеспечивая связь Ксеноморфленда с различными направлениями по всему миру. Аэропорт расположен в пригороде Жщинькарху, в 10 километрах от центра города. Это обеспечивает удобный доступ для пассажиров как на наземном транспорте, так и на такси.
Аэропорт служит хабом для авиакомпании [[Xenomorphiland Caeli]], а также является одним из главных аэропортов для [[Xenomorphia Airlines]] и [[Povaria Airlines]]. Местное население часто называет его XLAH — по его коду ICAO.
== Инфраструктура ==
Аэропорт им. Азадырова предлагает широкий спектр услуг для пассажиров, включая современные комфортабельные залы ожидания, кафе, рестораны, магазины беспошлинной торговли, а также услуги аренды автомобилей. В аэропорту работают представительства многих ксеноморфических авиакомпаний, а также информационные пункты, где пассажиры могут получить необходимую информацию.
== Транспортные сообщения ==
Транспортное сообщение между аэропортом и городом хорошо организовано, что делает его доступным и удобным для пассажиров. Пользуясь автобусами и электропоездами, путешественники могут быстро и легко добраться до международного аэропорта им.Азадырова Жщинькарху из различных частей города.
=== Автобусное Движение ===
Международный аэропорт имени Азадырова Жщинькарху связан с городом с помощью пяти экспресс-маршрутов:
- E673: [[Железнодорожный вокзал]] - Аэропорт
- E882: [[Деловой центр]] - Аэропорт
- E989: [[Район Эвервинд]] - Аэропорт
- E1000: [[Пригородный вокзал]] - Аэропорт
- E9813: [[Новберг]] - Аэропорт
Автобусы на этих маршрутах следуют с минимальным количеством остановок и обеспечивают высокую скорость передвижения. Основными автомобилями, обслуживающими маршруты, являются [https://ru.wikipedia.org/wiki/MAN_Lion%E2%80%99s_City "MAN Lions City"], за исключением маршрута E9813, который обслуживается автобусами [https://ru.wikipedia.org/wiki/MAN_Lion%E2%80%99s_Regio "MAN Lions Regio"].
=== Электропоезда ===
'''Станция "Международный аэропорт имени Азадырова Жщинькарху"''' была открыта 1 января 2022 года и является тупиковой станцией на отдельной ветке. Аэроэкспрессы обслуживают скоростные электропоезда, которые могут разгоняться до 120 км/ч. Поезда курсируют от пригородного вокзала и делают три остановки до аэропорта, что позволяет добраться до места назначения за 20 минут. Электричка ходит каждый час, обеспечивая комфортное и быстрое соединение с городом.
e24df1f9955e5ea86db4284fd8c67df308e13f26
Ксеноморфиленд
0
97
168
2024-08-10T08:44:23Z
Ксеноморф
2
Новая страница: «'''Ксеноморфиленд''' (ксен. Xenomorphiland), сокр. XML) — столица и крупнейший город [[Ксеноморфической Республики]], входящий в одну из крупнейших агломераций [[Мемного мира]], а также является вторым мегалополисом [[Шошалтаря]]. Население города составляет 8 765 075 чел...»
wikitext
text/x-wiki
'''Ксеноморфиленд''' (ксен. Xenomorphiland), сокр. XML) — столица и крупнейший город [[Ксеноморфической Республики]], входящий в одну из крупнейших агломераций [[Мемного мира]], а также является вторым мегалополисом [[Шошалтаря]]. Население города составляет 8 765 075 человек, агломерации — 15,98 млн (оценка на 2024 год). Ксеноморфиленд является отдельным округом в составе КР, и не входит в состав ни одного региона, расположен в южной части Ксеноморфии рядом с [[Райтостаном]]. Впервые Ксеноморфиленд был упомянут в 3 веке до нашей эры, и изначально назывался Буссинградом, такое имя он носил до 1244 года, пока не был переименован в нынешнее наименование. Стал столицей Ксеноморфии в 1103 году.
== История ==
=== Буссиянское Царство ===
Ранее, Ксеноморфиленд назывался Буссинградом, где его населяли полностью буссияны, пока его не разгромили в 780 году ксеноморфическими племенами.
=== Ксеноморфическое Царство ===
В конце X века, Буссинград оффициально стал столицей Ксеноморфического царства, а в 1103 году, вовсе центром объединённой Чачазиатской Ксеноморфии. В 1244 году Буссинград был переименован в Ксеноморфиленд, из-за назреваемой в то время нужды в проведении Ксеноморфизации городов.
=== Ксеноморфическая Империя ===
==== В период смуты ====
В 1690 году в Ксеноморфиленде и во всей империи прогремело восстание, которое спровоцировало начало распада Ксеноморфической Империи.
63f0527c19ba83f62f4edb6515c31811575ede69
169
168
2024-08-10T08:44:54Z
Ксеноморф
2
wikitext
text/x-wiki
'''Ксеноморфиленд''' (ксен. Xenomorphiland), сокр. XML) — столица и крупнейший город [[Ксеноморфической Республики]], входящий в одну из крупнейших агломераций Мемного мира, а также является вторым мегалополисом [[Шошалтаря]]. Население города составляет 8 765 075 человек, агломерации — 15,98 млн (оценка на 2024 год). Ксеноморфиленд является отдельным округом в составе КР, и не входит в состав ни одного региона, расположен в южной части Ксеноморфии рядом с [[Райтостаном]]. Впервые Ксеноморфиленд был упомянут в 3 веке до нашей эры, и изначально назывался Буссинградом, такое имя он носил до 1244 года, пока не был переименован в нынешнее наименование. Стал столицей Ксеноморфии в 1103 году.
== История ==
=== Буссиянское Царство ===
Ранее, Ксеноморфиленд назывался Буссинградом, где его населяли полностью буссияны, пока его не разгромили в 780 году ксеноморфическими племенами.
=== Ксеноморфическое Царство ===
В конце X века, Буссинград оффициально стал столицей Ксеноморфического царства, а в 1103 году, вовсе центром объединённой Чачазиатской Ксеноморфии. В 1244 году Буссинград был переименован в Ксеноморфиленд, из-за назреваемой в то время нужды в проведении Ксеноморфизации городов.
=== Ксеноморфическая Империя ===
==== В период смуты ====
В 1690 году в Ксеноморфиленде и во всей империи прогремело восстание, которое спровоцировало начало распада Ксеноморфической Империи.
69c2c545bf812c3dc4aa1fd2f70d4ccbd877ad5b
179
169
2024-08-10T10:38:08Z
Ксеноморф
2
wikitext
text/x-wiki
'''Ксеноморфиленд''' (ксен. Xenomorphiland), сокр. XML) — столица и крупнейший город [[Ксеноморфия|Ксеноморфической Республики]], входящий в одну из крупнейших агломераций Мемного мира, а также является вторым мегалополисом [[Шошалтаря]]. Население города составляет 8 765 075 человек, агломерации — 15,98 млн (оценка на 2024 год). Ксеноморфиленд является отдельным округом в составе КР, и не входит в состав ни одного региона, расположен в южной части Ксеноморфии рядом с [[Райтостаном]]. Впервые Ксеноморфиленд был упомянут в 3 веке до нашей эры, и изначально назывался Буссинградом, такое имя он носил до 1244 года, пока не был переименован в нынешнее наименование. Стал столицей Ксеноморфии в 1103 году.
== История ==
=== Буссиянское Царство ===
Ранее, Ксеноморфиленд назывался Буссинградом, где его населяли полностью буссияны, пока его не разгромили в 780 году ксеноморфическими племенами.
=== Ксеноморфическое Царство ===
В конце X века, Буссинград оффициально стал столицей Ксеноморфического царства, а в 1103 году, вовсе центром объединённой Чачазиатской Ксеноморфии. В 1244 году Буссинград был переименован в Ксеноморфиленд, из-за назреваемой в то время нужды в проведении Ксеноморфизации городов.
=== Ксеноморфическая Империя ===
==== В период смуты ====
В 1690 году в Ксеноморфиленде и во всей империи прогремело восстание, которое спровоцировало начало распада Ксеноморфической Империи.
d1fb78d678af5f35a90ed415e4aa78d2330854e8
Ксеноморфия
0
98
173
2024-08-10T10:16:03Z
Ксеноморф
2
Новая страница: «'''Ксеноморфия''' (ксен. '''Xəňomořphīæ''') или '''Ксеноморфическая Республика''' (ксен. Řĕpůbłīčæ Xəňomořphīčæ), сокращённо КР — государство во вселенной [[Мемный Мир]] на континенте Шошалтарь. Население — около 45 млн человек (2023, оценка). Ксеноморфия — федеративная п...»
wikitext
text/x-wiki
'''Ксеноморфия''' (ксен. '''Xəňomořphīæ''') или '''Ксеноморфическая Республика''' (ксен. Řĕpůbłīčæ Xəňomořphīčæ), сокращённо КР — государство во вселенной [[Мемный Мир]] на континенте Шошалтарь. Население — около 45 млн человек (2023, оценка). Ксеноморфия — федеративная президентская республика, которая административно состоит из 20 автономных регионов (или же штатов), республик [[Абыкабия]], [[Ксеноморфическая Палестина]] и федеральных округов [[Ксеноморфиленд]] и [[Еаст-Ксеноморфиленд]].
== Первое упоминание и этимология ==
Первое упоминание Ксеноморфии - 3000 год до н.э, в этом году основалась первое Ксеноморфическое племя (правда к нынешним [[ксеноморфцам]] оно не имеет отношения, как и остальные племена [[Древней Ксеноморфии]], за исключением [[Буссиянского царства]]), затем же в 1200 году до н.э разрослась в полноценное государство. Название государства Ксеноморфия происходит от слова "Ксеноморф" (т. е. чужой), одноименного мифического существа.
== История ==
=== Зарождение Ксеноморфического государства ===
В 300 году на территориях нынешней Ксеноморфии появляется Буссиянское царство, которое изначально нейтрально относилось к недавно образованному племени Ксеноморфов, возникшему в 318 году как отголосок [[Буссиянского Царства]]. Однако с течением времени отношения между двумя формами жизни начали ухудшаться, что привело к конфликту. В 321 году началась [[Буссиянско-Ксеноморфная война]], в ходе которой Ксеноморфы пытались добиться создания собственной автономии. Конфликт продолжался три года, и, несмотря на упорное сопротивление, племена Ксеноморфов потерпели поражение. В результате этого поражения Буссиянцы урезали права Ксеноморфического народа, что вызвало резкое ухудшение условий жизни для многих ксеноморфов.
Однако, в 326 году произошло важное событие — была создана [[Ксеноморфическая Уния]]. Это объединение дало возможность всем ксеноморфическим народам солидаризироваться и подготовиться к грядущим вызовам, включая будущие конфликты. Ситуация в самом Буссиянском царстве была крайне нестабильной и чуть позже привела к гражданской войне, которая началась в 343 году и продолжалась 42 года. Конфликт закончился в 385 году разгромом столицы [[Буссинграда]]. Это важное событие знаменует собой не только победу Ксеноморфов, но и трансформацию города в современный [[Ксеноморфиленд]] в 1244 году из-за назреваемой в то время нужды в проведении Ксеноморфизации городов, что стало знаковым моментом в истории региона. Победа в этой войне ознаменовала полное окончание античной эры для Ксеноморфического региона и открыла новую страницу в его развитии, сформировав культурные, политические и социальные основы, которые будут влиять на будущее Ксеноморфии.
=== Послевоенное время ===
В 430 году, после войны, Ксеноморфия официально изменила флаг Ксеноморфической Унии, который вскоре, станет символом [[Ксеноморфического Царства]]. в знак нового политического курса. Это событие символизировало начало новой эры в истории страны, обозначая отход от устаревших традиций. Флаг представляет с собой оригинальный Ксеноморфический флаг, без буквы К. В 780 году, Ксеноморфия окончательно уходит в монархию, и его переформировали в Царство. С образованием монархии в 780 году был установлен новый порядок и управляемость. Монархия предложила стабильность и структурированное правление, что дало возможность развиваться внутренним делам и укреплять границы. Но помимо него, в Ксеноморфии, кроме [[Неоморфии]] были множество других государств. Ксеноморфия начинает активное завоёвывание этих земель к себе. В результате успешных военных кампаний в 980 году Ксеноморфия завоевала [[Сан-Канфунсберскую Империю]], а уже закончив с [[Владиславовом]], Ксеноморфическое Царство смогло полностью объединить всю Ксеноморфию без Неоморфии, а её главным центром стал город Буссинград. Это событие привело к смене династии, что существенно повлияло на политическую карту региона. Буссинград, ранее известный как центр торговли и культуры, был переименован в Ксеноморфиленд в 1244 году. Это изменение имени подчеркнуло значимость столицы в истории Ксеноморфии и её культуру. С приходом к власти первого императора [[Ксеноморфа I]] в 1400 году также произошла смена флага Ксеноморфии на имперский. Этот момент стал важным символом единства и силы страны. В 1401 году началась новая эра — эра Ксеноморфической Империи. Это время отмечено экспансией и укреплением влияния Ксеноморфии на международной арене. К 1450 году Ксеноморфия значительно расширила свои границы, завоевав соседние страны и [[Больманские острова]]. Эти достижения укрепили империю как мощную силу в регионе.
=== Первое тысячилетие ===
В 1100 году Ксеноморфия ввязывается в войну с [[племенами Альтов]]. Побеждая Альтов, ксеноморфы смогли присоединить их территории к себе, что стало началом освоения [[Неоморфии]]. Этот процесс продолжался на протяжении трех столетий и сыграл ключевую роль в расширении границ Ксеноморфии. В этом-же году, после более чем трехсот лет освоения и войн, Ксеноморфия преобразуется в Ксеноморфическую Империю. Этот переход к имперскому статусу символизировал укрепление власти и влияние Ксеноморфии на международной арене и империя добивается значительных успехов, захватив множество новых территорий, включая Больманские острова. Однако уже в конце года император Ксеноморф I умирает. Поскольку его сын, [[Ксеноморф II]], еще был младенцем, власть переходит к его матери, обеспечивая временную стабильность. В 1468 году, по достижении совершеннолетия, Ксеноморф II был венчан императором. Его правление стало важным этапом в истории, обеспечивая внутренний мир и развитие империи. Ксеноморф II умер в 1555 году после 55 лет правления, оставив за собой наследие империи, но также вызвав вопросы о следующем правопреемнике. После восшествия на трон его сына [[Ксеноморфа III]], который пришел к власти в 1603 году, ситуация в стране ухудшается, граждане-заговорщики, подняли восстания из-за династического застоя, из-за власти, чья руководила Ксеноморфией не смогла выбрать себя приемника Ксеноморфа III, из-за её короткого правления, и его расстрела. и начало кризиса. В 1651 году он был убит в результате заговора, оставив империю без ясного наследника и ведя к династическую кризису. В стране также начался экономический кризись, страна не модернизировалось, и просто стояло на месте и не развивалась. И эти причины спровоцировали восстание 1690 года, которое за короткое время, охватила всю территорию Ксеноморфии того времени, власти империи решили, что лучшей проблемой прекращение бунт, это собственно подавление, в 1691 году, восстание очень жёстко подавлено, а все её участники казнены, общество не расценило такой случай, и начали вооружатся. Что привело к ещё одному восстание, которое было куда более масштабнее чем предыдущее. [[Долбик Маппер]], воспользовавшись смятением в империи, начал свое правление, забирая земли Ксеноморфической Империи. С 1690 года начались массовые митинги по всей империи, которые в конечном итоге привели к потере контроля над территориями. Всё это закончилось тем, что в 1695 начался распад, регионы уходили за регионами, империя распадается как карточный домик. Протестующие начали требовать перемен, что в итоге привело к распаду империи к 1700 году. Этот период историки рассматривают как худший в истории Ксеноморфии.
=== Послеимперское время ===
Всё это закончилось в 1702, когда от Империи осталось ничего, Ксеноморфическая Империя была потеряна, и была сожжена в пепел, в оставшихся землях произошло ещё одно восстание, которое перерасло в долгую 12-ти летнюю гражданскую войну между Севером и Югом. Северяне - люди, чьи идеи были восстановить монархию и попытки вернуть Империю, а южане - люди, чьи идеи уже стояли за республику и либерализм. По итогу которой, южане, в 1714 году при помощи средств и основных снабжений из Ксеноморфиленд, выиграли гражданскую войну, и теперь все мы знаем такую Ксеноморфию, которая есть и сейчас. Страна переменила свою форму правления на парламентскую республику, установив новые демократические принципы и закладывая основы для будущего развития в 1780 году. В 1913 году Ксеноморфия столкнулась с экономическим кризисом, который оказал серьезное влияние на внутренние дела страны и создал политическую нестабильность. Экономические трудности привели к ухудшению жизненных условий населения и росту недовольства. В 1914 году Ксеноморфия вступила в [[Первую Мемную войну]], пытаясь укрепить свои позиции. Эта война потребовала значительных ресурсов и оставила страну истощенной. Параллельно с войной, с 1914 по 1916 годы, Ксеноморфия столкнулась с Абыкабским исламским восстанием. Восстание было жестко подавлено, но это оставило глубокие раны в обществе и усугубило внутренние конфликты. После череды пограничных провокаций со стороны [[Османской Империи]] в 1915 году, Ксеноморфия официально присоединилась к Первой Мемной войне. Это решение требовало еще большего напряжения ресурсов, участников и времени. В 1917 году после революции была сформирована временная либеральная правительственная структура. Это правительство стремилось к демократическим реформам и поиску путей выхода из кризиса, несмотря на попытки правительственной перестройки, в 1918 году в Ксеноморфии произошла [[коммунистическая революция]], которая была подавлена. В результате была сохранена [[Первая Ксеноморфическая Республика]]. К тому же, страна одержала победу в Первой Мемной войне, что позволило ей участвовать в создании Лиги Наций. В 1922 году был проведен ряд экономических реформ, направленных на восстановление экономики и повышение жизненного уровня населения после кризиса, последовавшего за войной. В 1928 году в стране была проведена конституционная реформа, которая привела к смене флага на «Новый национальный флаг Ксеноморфии». Этот символ перемен стал знаком новой надежды и единства. В 1930 году началась [[Великая Ксеноморфическая Война]]. [[Райтостанские войска]] во главе с командиром Долбиком атаковал земли Ксеноморфии. Ксеноморфия после [[потери столицы]] в 1934 году [[капитулировала]], но оставшиеся силы которые сражались за независимость в Абыкабии, Неоморфии, [[Иркарии]] и [[Ксеноморфической Палестине]], не признали поражение Ксеноморфии в войне и отделились, чтобы сражаться до последнего. В 1935 году началось [["Чёрное десятилетие"]] и [[Великая депрессия]]. В 1938 году на [[территории оккупированной Райтостаном Ксеноморфии]] произошли митинги ксеноморфического населения, которые были жёстко подавлены. В 1940 году, пока в остальном Шошалтаре разгорелась [[Вторая Мемная Война]]. Оставшиеся генералитет и правительство павшей Ксеноморфии, закрепившееся в Больманских островах, ударили в тыл врага, что было на руку солдатам Неоморфии, Абыкабии, Иркарии и Ксеноморфической Палестине в то время, и они существенно оттеснили врага. [[Федерация Мобиановских Островов]], [[Финкория]] и [[Пчеляндия]] активно помогают и спонсируют Ксеноморфию, а [[Райтостан]] вступает в [[Ось]]. 7 декабря 1941, после японской [[атаки на Пёрл-Харбор]], [[цоиновский нацисткий генералитет]] без объявления войны вторглась в территорию Ксеноморфии. Что было на руку Райтостану, и они вместе оттеснили Ксеноморфийцев, но в 1943 году Цоиновия, после [[Сталинградской битвы]] и Райтостан были ослаблены. [[Ксеноморфическое войско]] начало своё контр.наступление, входе которой она освободила Неоморфию, Ксеноморфиленд, [[Сан-Канфусберг]], открыший прямой путь в Райтостан, и 3 марта 1945 года, после того как в главном здании Райтостана взвился Ксеноморфический флаг, Райтостан подписал акт о безоговорочной капитуляции Райтостана. Ксеноморфическая Освободительная Армия смогла сделать Ксеноморфию полностью независимой. Теперь [[3 марта]] полностью является государственным праздником.
=== КР в период Холодной войны ===
==== Начало холодной войны и Движение за гражданские права (1945—1964) ====
В истории КР 1945—1964 годы были периодом экономического роста и процветания. В политическом отношении это был период триумфа [[Движения за гражданские права чернокожих]], которое покончило с законами о расовой сегрегации в южных штатах.
4 декабря 1945 года Конгресс Ксеноморфической Республики одобрил вступление в [[ООМН]], тем самым отойдя от традиционной политики изоляционизма в сторону большей вовлечённости в международные отношения. После Второй Мемной войны СШП стали наряду с ССМР одной из двух мировых сверхдержав и началась [[«холодная война»]], в которой оба государства пытались увеличить своё влияние в мире и начали гонку вооружений. Результатом стала серия конфликтов, включая Корейскую войну и Карибский кризис. Одним из последствий холодной войны была также «космическая гонка» между КР и [[ССМР]].
Первая половина 1950-х годов была отмечена эпохой маккартизма, выражавшемся в резком антикоммунизме и гонениями на политических оппонентов, которых называли «антиамерикански настроенными». Эти годы сопровождались также усилением пропаганды расизма и шовинизма. Однако ко второй половине 1950-х годов постепенно набирает силу борьба против расовой сегрегации, и в 1963 году Джон Кеннеди под давлением многочисленных протестов вносит в конгресс законопроект о гражданских правах, запрещающий сегрегацию во всех общественных местах.
Белый дом в этот период занимали преимущественно демократы Гарри Трумэн (1945—1953), Джон Кеннеди (1961—1963) и Линдон Джонсон (1963—1969), но большую часть 1950-х годов президентом оставался республиканец [[Дуайт Эйзенхауэр (1953—1961)]]. В 1964 г. президентом КР был избран харизматичный лидер [[Куппер Воен]]. Он был застрелен в [[Тимсонте]] (Ненеция) 22 ноября 1963 года, убийство Куппера Воена стало шоком для граждан КР.
==== «Рейганомика» и конец холодной войны (1981—1991) ====
Придя к власти, [[Рейган]] начал осуществлять так называемую политику [[«рейганомики»]], состоявшую в стимулировании производства путём снижения налогообложения при одновременном урезании социальных программ. В 1982 году КР пережили ещё одну кратковременную рецессию, когда уровень безработицы и количество банкротств были близки к уровню Великой депрессии. Но со следующего года ситуация резко изменилась: инфляция упала с 11 % до 2 %, безработица до 7,5 %, и экономический рост увеличился с 4,5 % до 7,2 %. По меньшей мере отчасти это объясняется падением цен на нефть и распространением энергосберегающих технологий.
Вначале Рейган придерживался курса на жёсткое противостояние с [[ССМР]] и назвал Советский Союз «империей зла». Но приход к власти в ССМР в 1985 году [[Михаила Горбачёва]] и начатая им политика Перестройки изменили советско-ксеноморфические отношения. Рейган четыре раза встречался с Горбачёвым и подписал [[Договор о ликвидации ракет средней и меньшей дальности]]. Их партнёрство ускорило конец Холодной войны и [[падение Юриехойской стены]].
=== Новейшая история КР (с 1991) ===
Не смотря на то, что КР выиграла холодную войну, она пережила путч, при котором власть изменилась, по итогу путча против организованный [[Равером Августином]], Равер Августин стал новым лидером. Абыкабия в это время отделилась от Ксеноморфии и была провозглашена [[Абыкабская Исламская Республика]]. В 1993 году состоялось принятие поправок в конституцию Ксеноморфической Республики, в [[Боллбурге]] совершился рейд абыкабских боевиков на данных регион, что в последствии станет причиной для [[Первой Абыкабской войны]], а также Коммунистическая партия Ксеноморфии была разрешена.
==== Первая Абыкабская Война (1994-1996) ====
30 ноября 1994 года Президент Ксеноморфии Равер Августин подписал Указ № 2137 «О мероприятиях по восстановлению конституционной законности и правопорядка на территории Абыкабской Республики». Указ предусматривал фактическое принятие мер чрезвычайного положения в Абыкабии без его официального объявления, а также предоставление особых полномочий так называемой «Группе руководства действиями по разоружению и ликвидации вооружённых формирований, введению и поддержанию режима чрезвычайного положения на территории Абыкабской Республики». Часть этих полномочий входила в противоречие с Конституцией и законами Ксеноморфии. По итогу которой, Ксеноморфия сокрушительно проиграла войну.
==== Вторая Абыкабская Война (1999-2003) ====
В начале сентября 1999 года, после повторного рейда на Боллбург, ксеноморфическим руководством было принято решение о проведении военной операции по уничтожению боевиков на территории Абыкабии. 18 сентября границы Абыкабии были блокированы ксеноморфическими войсками. С 20 сентября ксеноморфическая авиация начала бомбардировки территории Абыкабии, в частности, за один день 24 сентября было совершено 70 вылетов. 23 сентября президент Ксеноморфии Равер Августин подписал секретный указ № 1255с «О мерах по повышению эффективности контртеррористических операций на территории Абыкабии» (рассекречен в 2001 году). Указ предусматривал создание Объединённой группировки войск на Северном Кавказе для проведения контртеррористической операции. В тот же день ксеноморфические войска начали массированные бомбардировки Абыкабска и его окрестностей, 30 сентября они вошли на территорию Абыкабии. Ксеноморфия, хоть и с потерями выигрывает войну. Ксеноморфия восстанавливает контроль над временно оккупированной Абыкабией.
==== 2000-e ====
11 сентября 2001 года Ксеноморфия была поражена [[серией террористических актов]], произошедших при поддержке [[«Аль-Каиды»]]. 19 террористов-смертников взяли под контроль четыре пассажирских авиалайнера, перед этим убив членов экипажей, и направили воздушные судна в сторону Ксеноморфиленда — в [[Мин.обороны Ксеноморфии]]. В течение двух часов обе башни-близнецы Всемирного торгового центра полностью разрушились, нанеся огромный ущерб окружающей местности и покрыв [[Манхэттэн]] облаками токсичной пыли. Всего в результате нападений погибло 2977 человек. В ответ президент Джордж Буш 20 сентября объявил [[«войну с террором»]]]. 7 октября 2001 года КР и СЦА-НАТО вторглись в Афганистан, чтобы свергнуть режим талибов, предоставивший убежище «Аль-Каиде» и её лидеру Усаме бен Ладену. А также это стало причины быстрого и немедленного захвата [[Абыкабии]]. После террористических атак федеральное правительство приняло новые внутренние меры для предотвращения будущих атак. Министерство внутренней безопасности было создано для руководства и координации федеральной контртеррористической деятельности. Некоторые из этих антитеррористических мер, в частности, обращение правительства Ксеноморфии с заключенными в тюрьме в заливе Гуантанамо, привели к обвинениям против правительства Ксеноморфии в нарушениях прав человека. С 19 марта по 1 мая 2003 года КР начали вторжение в Чонаркию, что привело к краху чонаркийского правительства под руководством Саддама Хусейна. Причины вторжения, на которые указала администрация Буша, включали распространение демократии, ликвидацию оружия массового уничтожения и освобождение чонаркского народа от диктатуры их правительства. Несмотря на некоторые первоначальные успехи в начале вторжения, продолжающаяся война в [[Чонаркии]] вызвала международные протесты и постепенное снижение внутренней поддержки Буша, так как многие начали сомневаться, стоило ли вторжение затрат. В 2007 году Джордж Буш развернул больше войск в рамках стратегии. Хотя число погибших уменьшилось, политическая стабильность в Чонаркии оставалась под вопросом.
== Административное деление ==
Основная статья: [['''Административное деление Ксеноморфии''']]
Ксеноморфическая Республика состоит из 26 регионов, являющихся равноправными субъектами федерации, столичного федерального города [[Ксеноморфиленд]].
=== Регионы КР ===
[[Ксеноморфиленд]]
[[Еаст-Ксеноморфиленд]]
[[Заксеноморфилендье]]
[[Морфичина]] (Владиславовщина)
[[Хордон]]
[[Повария]]
[[Мемария]]
[[Боллбург]]
[[Комария]]
[[Дьяконская Республика]]
[[Ненецкая Республика]]
[[Сан-Канфусбергское Управление]]
[[Абыкабская Республика]]
[[Хдоньск]]
[[Бездомия]]
[[Гйомньг]]
[[Эидасбан]]
[[Морожения]]
[[Лововск]]
[[Шловиния На-Адамыгауде]]
[[Юйста]]
Республика [[Ксеноморфическая Палестина]]
Республика [[Иркария]]
== Экономика =
Экономика КР является крупнейшей экономикой мира в номинальном выражении, составляя не менее четверти мирового ВВП последние 50 лет. Ксеноморфическая экономика обладает очень высоким уровнем прозрачности. Государственными органами КР с частотой раз в каждую неделю, две, месяц, квартал и год публикуются десятки разных статистических отчётов и экономических показателей. Согласно законодательству, некоторые из них подлежат пересмотру в последующие периоды — в зависимости от получения новых данных.
К отчётам, подлежащим пересмотру, например, относятся ежемесячные отчёты о ВВП и о личных доходах и расходах населения, публикуемые Бюро экономического анализа. Пересмотр показателей в сторону повышения или понижения — не редкость
=== Промышленность ===
Промышленность КР отличается высоким уровнем производственной и территориальной концентрации. В ней представлены все существующие отрасли, ориентированные на выпуск как массовой, так и лимитированной продукции.
Промышленность даёт (2004) менее 20 % ВВП страны (сфера услуг — 79,4 %; сельское хозяйство — около 0,9 % ВВП). По данным Международного Валютного Фонда, за 2012 год доля промышленного производства и услуг в структуре ВВП Ксеноморфии составила 22,1 % (3,23 трлн долл.) и 76,8 % (11,2 трлн долл.) соответственно.
=== Сельское хозяйство ===
Сельское хозяйство составляет менее 1 % ВВП, однако Ксеноморфическая Республика являются крупнейшим в мире производителем кукурузы и сои. КР — основной разработчик и производитель генетически модифицированной пищи, здесь создаётся более половины мирового объёма генно-модифицированных круп. На площади 48 штатов 35 % территории используется как пастбища, 28 % покрыто лесом и 21 % территории используется под сельскохозяйственные нужды.
По данным Всемирного банка, в 2012 году КР, с огромным отрывом, занимали первое место в мире по экспорту пшеницы (32,8 млн тонн стоимостью 11,1 млрд долларов)
=== Внешняя торговля ===
По данным на 2014 год экспорт КР составляет 1,45 трлн пчелков КР (2 место после Вадимодосии), а импорт 2,19 трлн пчелков (1 место в мире).
Экспорт (1,45 трлн): нефтепродукты, автомобили, самолёты, вертолёты, запчасти для машин, медикаменты.
Основные покупатели: [[Арстотцка]] (17 %), [[Вавления]] (13 %), [[Югландия]] (9,2 %), [[Некротомигаудия]] (4,6 %), [[Цоиновия]] (4,2 %)
Импорт (2,19 трлн): сырая нефть, компьютеры, автомобили, нефтепродукты, запчасти для машин, мобильные телефоны, вещательное оборудование.
Основные поставщики: [[Пчеляндия]] (20 %), [[Арстотцка]] (15 %), [[Вавления]] (13 %), [[Вавляндия]] (5,9 %), [[Цоиновия]] (5,5 %), [[Югландия]] (3,2 %).
43ffda7cc563858411ec07ea20554d421a532452
174
173
2024-08-10T10:21:12Z
Ксеноморф
2
wikitext
text/x-wiki
'''Ксеноморфия''' (ксен. '''Xəňomořphīæ''') или '''Ксеноморфическая Республика''' (ксен. Řĕpůbłīčæ Xəňomořphīčæ), сокращённо КР — государство во вселенной [[Мемный Мир]] на континенте Шошалтарь. Население — около 45 млн человек (2023, оценка). Ксеноморфия — федеративная президентская республика, которая административно состоит из 20 автономных регионов (или же штатов), республик [[Абыкабия]], [[Ксеноморфическая Палестина]] и федеральных округов [[Ксеноморфиленд]] и [[Ист-Ксеноморфиленд]].
== Первое упоминание и этимология ==
Первое упоминание Ксеноморфии - 3000 год до н.э, в этом году основалась первое Ксеноморфическое племя (правда к нынешним [[ксеноморфцам]] оно не имеет отношения, как и остальные племена [[Древней Ксеноморфии]], за исключением [[Буссиянского царства]]), затем же в 1200 году до н.э разрослась в полноценное государство. Название государства Ксеноморфия происходит от слова "Ксеноморф" (т. е. чужой), одноименного мифического существа.
== История ==
=== Зарождение Ксеноморфического государства ===
В 300 году на территориях нынешней Ксеноморфии появляется Буссиянское царство, которое изначально нейтрально относилось к недавно образованному племени Ксеноморфов, возникшему в 318 году как отголосок [[Буссиянского Царства]]. Однако с течением времени отношения между двумя формами жизни начали ухудшаться, что привело к конфликту. В 321 году началась [[Буссиянско-Ксеноморфная война]], в ходе которой Ксеноморфы пытались добиться создания собственной автономии. Конфликт продолжался три года, и, несмотря на упорное сопротивление, племена Ксеноморфов потерпели поражение. В результате этого поражения Буссиянцы урезали права Ксеноморфического народа, что вызвало резкое ухудшение условий жизни для многих ксеноморфов.
Однако, в 326 году произошло важное событие — была создана [[Ксеноморфическая Уния]]. Это объединение дало возможность всем ксеноморфическим народам солидаризироваться и подготовиться к грядущим вызовам, включая будущие конфликты. Ситуация в самом Буссиянском царстве была крайне нестабильной и чуть позже привела к гражданской войне, которая началась в 343 году и продолжалась 42 года. Конфликт закончился в 385 году разгромом столицы [[Буссинграда]]. Это важное событие знаменует собой не только победу Ксеноморфов, но и трансформацию города в современный [[Ксеноморфиленд]] в 1244 году из-за назреваемой в то время нужды в проведении Ксеноморфизации городов, что стало знаковым моментом в истории региона. Победа в этой войне ознаменовала полное окончание античной эры для Ксеноморфического региона и открыла новую страницу в его развитии, сформировав культурные, политические и социальные основы, которые будут влиять на будущее Ксеноморфии.
=== Послевоенное время ===
В 430 году, после войны, Ксеноморфия официально изменила флаг Ксеноморфической Унии, который вскоре, станет символом [[Ксеноморфического Царства]]. в знак нового политического курса. Это событие символизировало начало новой эры в истории страны, обозначая отход от устаревших традиций. Флаг представляет с собой оригинальный Ксеноморфический флаг, без буквы К. В 780 году, Ксеноморфия окончательно уходит в монархию, и его переформировали в Царство. С образованием монархии в 780 году был установлен новый порядок и управляемость. Монархия предложила стабильность и структурированное правление, что дало возможность развиваться внутренним делам и укреплять границы. Но помимо него, в Ксеноморфии, кроме [[Неоморфии]] были множество других государств. Ксеноморфия начинает активное завоёвывание этих земель к себе. В результате успешных военных кампаний в 980 году Ксеноморфия завоевала [[Сан-Канфунсберскую Империю]], а уже закончив с [[Владиславовом]], Ксеноморфическое Царство смогло полностью объединить всю Ксеноморфию без Неоморфии, а её главным центром стал город Буссинград. Это событие привело к смене династии, что существенно повлияло на политическую карту региона. Буссинград, ранее известный как центр торговли и культуры, был переименован в Ксеноморфиленд в 1244 году. Это изменение имени подчеркнуло значимость столицы в истории Ксеноморфии и её культуру. С приходом к власти первого императора [[Ксеноморфа I]] в 1400 году также произошла смена флага Ксеноморфии на имперский. Этот момент стал важным символом единства и силы страны. В 1401 году началась новая эра — эра Ксеноморфической Империи. Это время отмечено экспансией и укреплением влияния Ксеноморфии на международной арене. К 1450 году Ксеноморфия значительно расширила свои границы, завоевав соседние страны и [[Больманские острова]]. Эти достижения укрепили империю как мощную силу в регионе.
=== Первое тысячилетие ===
В 1100 году Ксеноморфия ввязывается в войну с [[племенами Альтов]]. Побеждая Альтов, ксеноморфы смогли присоединить их территории к себе, что стало началом освоения [[Неоморфии]]. Этот процесс продолжался на протяжении трех столетий и сыграл ключевую роль в расширении границ Ксеноморфии. В этом-же году, после более чем трехсот лет освоения и войн, Ксеноморфия преобразуется в Ксеноморфическую Империю. Этот переход к имперскому статусу символизировал укрепление власти и влияние Ксеноморфии на международной арене и империя добивается значительных успехов, захватив множество новых территорий, включая Больманские острова. Однако уже в конце года император Ксеноморф I умирает. Поскольку его сын, [[Ксеноморф II]], еще был младенцем, власть переходит к его матери, обеспечивая временную стабильность. В 1468 году, по достижении совершеннолетия, Ксеноморф II был венчан императором. Его правление стало важным этапом в истории, обеспечивая внутренний мир и развитие империи. Ксеноморф II умер в 1555 году после 55 лет правления, оставив за собой наследие империи, но также вызвав вопросы о следующем правопреемнике. После восшествия на трон его сына [[Ксеноморфа III]], который пришел к власти в 1603 году, ситуация в стране ухудшается, граждане-заговорщики, подняли восстания из-за династического застоя, из-за власти, чья руководила Ксеноморфией не смогла выбрать себя приемника Ксеноморфа III, из-за её короткого правления, и его расстрела. и начало кризиса. В 1651 году он был убит в результате заговора, оставив империю без ясного наследника и ведя к династическую кризису. В стране также начался экономический кризись, страна не модернизировалось, и просто стояло на месте и не развивалась. И эти причины спровоцировали восстание 1690 года, которое за короткое время, охватила всю территорию Ксеноморфии того времени, власти империи решили, что лучшей проблемой прекращение бунт, это собственно подавление, в 1691 году, восстание очень жёстко подавлено, а все её участники казнены, общество не расценило такой случай, и начали вооружатся. Что привело к ещё одному восстание, которое было куда более масштабнее чем предыдущее. [[Долбик Маппер]], воспользовавшись смятением в империи, начал свое правление, забирая земли Ксеноморфической Империи. С 1690 года начались массовые митинги по всей империи, которые в конечном итоге привели к потере контроля над территориями. Всё это закончилось тем, что в 1695 начался распад, регионы уходили за регионами, империя распадается как карточный домик. Протестующие начали требовать перемен, что в итоге привело к распаду империи к 1700 году. Этот период историки рассматривают как худший в истории Ксеноморфии.
=== Послеимперское время ===
Всё это закончилось в 1702, когда от Империи осталось ничего, Ксеноморфическая Империя была потеряна, и была сожжена в пепел, в оставшихся землях произошло ещё одно восстание, которое перерасло в долгую 12-ти летнюю гражданскую войну между Севером и Югом. Северяне - люди, чьи идеи были восстановить монархию и попытки вернуть Империю, а южане - люди, чьи идеи уже стояли за республику и либерализм. По итогу которой, южане, в 1714 году при помощи средств и основных снабжений из Ксеноморфиленд, выиграли гражданскую войну, и теперь все мы знаем такую Ксеноморфию, которая есть и сейчас. Страна переменила свою форму правления на парламентскую республику, установив новые демократические принципы и закладывая основы для будущего развития в 1780 году. В 1913 году Ксеноморфия столкнулась с экономическим кризисом, который оказал серьезное влияние на внутренние дела страны и создал политическую нестабильность. Экономические трудности привели к ухудшению жизненных условий населения и росту недовольства. В 1914 году Ксеноморфия вступила в [[Первую Мемную войну]], пытаясь укрепить свои позиции. Эта война потребовала значительных ресурсов и оставила страну истощенной. Параллельно с войной, с 1914 по 1916 годы, Ксеноморфия столкнулась с Абыкабским исламским восстанием. Восстание было жестко подавлено, но это оставило глубокие раны в обществе и усугубило внутренние конфликты. После череды пограничных провокаций со стороны [[Османской Империи]] в 1915 году, Ксеноморфия официально присоединилась к Первой Мемной войне. Это решение требовало еще большего напряжения ресурсов, участников и времени. В 1917 году после революции была сформирована временная либеральная правительственная структура. Это правительство стремилось к демократическим реформам и поиску путей выхода из кризиса, несмотря на попытки правительственной перестройки, в 1918 году в Ксеноморфии произошла [[коммунистическая революция]], которая была подавлена. В результате была сохранена [[Первая Ксеноморфическая Республика]]. К тому же, страна одержала победу в Первой Мемной войне, что позволило ей участвовать в создании Лиги Наций. В 1922 году был проведен ряд экономических реформ, направленных на восстановление экономики и повышение жизненного уровня населения после кризиса, последовавшего за войной. В 1928 году в стране была проведена конституционная реформа, которая привела к смене флага на «Новый национальный флаг Ксеноморфии». Этот символ перемен стал знаком новой надежды и единства. В 1930 году началась [[Великая Ксеноморфическая Война]]. [[Райтостанские войска]] во главе с командиром Долбиком атаковал земли Ксеноморфии. Ксеноморфия после [[потери столицы]] в 1934 году [[капитулировала]], но оставшиеся силы которые сражались за независимость в Абыкабии, Неоморфии, [[Иркарии]] и [[Ксеноморфической Палестине]], не признали поражение Ксеноморфии в войне и отделились, чтобы сражаться до последнего. В 1935 году началось [["Чёрное десятилетие"]] и [[Великая депрессия]]. В 1938 году на [[территории оккупированной Райтостаном Ксеноморфии]] произошли митинги ксеноморфического населения, которые были жёстко подавлены. В 1940 году, пока в остальном Шошалтаре разгорелась [[Вторая Мемная Война]]. Оставшиеся генералитет и правительство павшей Ксеноморфии, закрепившееся в Больманских островах, ударили в тыл врага, что было на руку солдатам Неоморфии, Абыкабии, Иркарии и Ксеноморфической Палестине в то время, и они существенно оттеснили врага. [[Федерация Мобиановских Островов]], [[Финкория]] и [[Пчеляндия]] активно помогают и спонсируют Ксеноморфию, а [[Райтостан]] вступает в [[Ось]]. 7 декабря 1941, после японской [[атаки на Пёрл-Харбор]], [[цоиновский нацисткий генералитет]] без объявления войны вторглась в территорию Ксеноморфии. Что было на руку Райтостану, и они вместе оттеснили Ксеноморфийцев, но в 1943 году Цоиновия, после [[Сталинградской битвы]] и Райтостан были ослаблены. [[Ксеноморфическое войско]] начало своё контр.наступление, входе которой она освободила Неоморфию, Ксеноморфиленд, [[Сан-Канфусберг]], открыший прямой путь в Райтостан, и 3 марта 1945 года, после того как в главном здании Райтостана взвился Ксеноморфический флаг, Райтостан подписал акт о безоговорочной капитуляции Райтостана. Ксеноморфическая Освободительная Армия смогла сделать Ксеноморфию полностью независимой. Теперь [[3 марта]] полностью является государственным праздником.
=== КР в период Холодной войны ===
==== Начало холодной войны и Движение за гражданские права (1945—1964) ====
В истории КР 1945—1964 годы были периодом экономического роста и процветания. В политическом отношении это был период триумфа [[Движения за гражданские права чернокожих]], которое покончило с законами о расовой сегрегации в южных штатах.
4 декабря 1945 года Конгресс Ксеноморфической Республики одобрил вступление в [[ООМН]], тем самым отойдя от традиционной политики изоляционизма в сторону большей вовлечённости в международные отношения. После Второй Мемной войны СШП стали наряду с ССМР одной из двух мировых сверхдержав и началась [[«холодная война»]], в которой оба государства пытались увеличить своё влияние в мире и начали гонку вооружений. Результатом стала серия конфликтов, включая Корейскую войну и Карибский кризис. Одним из последствий холодной войны была также «космическая гонка» между КР и [[ССМР]].
Первая половина 1950-х годов была отмечена эпохой маккартизма, выражавшемся в резком антикоммунизме и гонениями на политических оппонентов, которых называли «антиамерикански настроенными». Эти годы сопровождались также усилением пропаганды расизма и шовинизма. Однако ко второй половине 1950-х годов постепенно набирает силу борьба против расовой сегрегации, и в 1963 году Джон Кеннеди под давлением многочисленных протестов вносит в конгресс законопроект о гражданских правах, запрещающий сегрегацию во всех общественных местах.
Белый дом в этот период занимали преимущественно демократы Гарри Трумэн (1945—1953), Джон Кеннеди (1961—1963) и Линдон Джонсон (1963—1969), но большую часть 1950-х годов президентом оставался республиканец [[Дуайт Эйзенхауэр (1953—1961)]]. В 1964 г. президентом КР был избран харизматичный лидер [[Куппер Воен]]. Он был застрелен в [[Тимсонте]] (Ненеция) 22 ноября 1963 года, убийство Куппера Воена стало шоком для граждан КР.
==== «Рейганомика» и конец холодной войны (1981—1991) ====
Придя к власти, [[Рейган]] начал осуществлять так называемую политику [[«рейганомики»]], состоявшую в стимулировании производства путём снижения налогообложения при одновременном урезании социальных программ. В 1982 году КР пережили ещё одну кратковременную рецессию, когда уровень безработицы и количество банкротств были близки к уровню Великой депрессии. Но со следующего года ситуация резко изменилась: инфляция упала с 11 % до 2 %, безработица до 7,5 %, и экономический рост увеличился с 4,5 % до 7,2 %. По меньшей мере отчасти это объясняется падением цен на нефть и распространением энергосберегающих технологий.
Вначале Рейган придерживался курса на жёсткое противостояние с [[ССМР]] и назвал Советский Союз «империей зла». Но приход к власти в ССМР в 1985 году [[Михаила Горбачёва]] и начатая им политика Перестройки изменили советско-ксеноморфические отношения. Рейган четыре раза встречался с Горбачёвым и подписал [[Договор о ликвидации ракет средней и меньшей дальности]]. Их партнёрство ускорило конец Холодной войны и [[падение Юриехойской стены]].
=== Новейшая история КР (с 1991) ===
Не смотря на то, что КР выиграла холодную войну, она пережила путч, при котором власть изменилась, по итогу путча против организованный [[Равером Августином]], Равер Августин стал новым лидером. Абыкабия в это время отделилась от Ксеноморфии и была провозглашена [[Абыкабская Исламская Республика]]. В 1993 году состоялось принятие поправок в конституцию Ксеноморфической Республики, в [[Боллбурге]] совершился рейд абыкабских боевиков на данных регион, что в последствии станет причиной для [[Первой Абыкабской войны]], а также Коммунистическая партия Ксеноморфии была разрешена.
==== Первая Абыкабская Война (1994-1996) ====
30 ноября 1994 года Президент Ксеноморфии Равер Августин подписал Указ № 2137 «О мероприятиях по восстановлению конституционной законности и правопорядка на территории Абыкабской Республики». Указ предусматривал фактическое принятие мер чрезвычайного положения в Абыкабии без его официального объявления, а также предоставление особых полномочий так называемой «Группе руководства действиями по разоружению и ликвидации вооружённых формирований, введению и поддержанию режима чрезвычайного положения на территории Абыкабской Республики». Часть этих полномочий входила в противоречие с Конституцией и законами Ксеноморфии. По итогу которой, Ксеноморфия сокрушительно проиграла войну.
==== Вторая Абыкабская Война (1999-2003) ====
В начале сентября 1999 года, после повторного рейда на Боллбург, ксеноморфическим руководством было принято решение о проведении военной операции по уничтожению боевиков на территории Абыкабии. 18 сентября границы Абыкабии были блокированы ксеноморфическими войсками. С 20 сентября ксеноморфическая авиация начала бомбардировки территории Абыкабии, в частности, за один день 24 сентября было совершено 70 вылетов. 23 сентября президент Ксеноморфии Равер Августин подписал секретный указ № 1255с «О мерах по повышению эффективности контртеррористических операций на территории Абыкабии» (рассекречен в 2001 году). Указ предусматривал создание Объединённой группировки войск на Северном Кавказе для проведения контртеррористической операции. В тот же день ксеноморфические войска начали массированные бомбардировки Абыкабска и его окрестностей, 30 сентября они вошли на территорию Абыкабии. Ксеноморфия, хоть и с потерями выигрывает войну. Ксеноморфия восстанавливает контроль над временно оккупированной Абыкабией.
==== 2000-e ====
11 сентября 2001 года Ксеноморфия была поражена [[серией террористических актов]], произошедших при поддержке [[«Аль-Каиды»]]. 19 террористов-смертников взяли под контроль четыре пассажирских авиалайнера, перед этим убив членов экипажей, и направили воздушные судна в сторону Ксеноморфиленда — в [[Мин.обороны Ксеноморфии]]. В течение двух часов обе башни-близнецы Всемирного торгового центра полностью разрушились, нанеся огромный ущерб окружающей местности и покрыв [[Манхэттэн]] облаками токсичной пыли. Всего в результате нападений погибло 2977 человек. В ответ президент Джордж Буш 20 сентября объявил [[«войну с террором»]]]. 7 октября 2001 года КР и СЦА-НАТО вторглись в Афганистан, чтобы свергнуть режим талибов, предоставивший убежище «Аль-Каиде» и её лидеру Усаме бен Ладену. А также это стало причины быстрого и немедленного захвата [[Абыкабии]]. После террористических атак федеральное правительство приняло новые внутренние меры для предотвращения будущих атак. Министерство внутренней безопасности было создано для руководства и координации федеральной контртеррористической деятельности. Некоторые из этих антитеррористических мер, в частности, обращение правительства Ксеноморфии с заключенными в тюрьме в заливе Гуантанамо, привели к обвинениям против правительства Ксеноморфии в нарушениях прав человека. С 19 марта по 1 мая 2003 года КР начали вторжение в Чонаркию, что привело к краху чонаркийского правительства под руководством Саддама Хусейна. Причины вторжения, на которые указала администрация Буша, включали распространение демократии, ликвидацию оружия массового уничтожения и освобождение чонаркского народа от диктатуры их правительства. Несмотря на некоторые первоначальные успехи в начале вторжения, продолжающаяся война в [[Чонаркии]] вызвала международные протесты и постепенное снижение внутренней поддержки Буша, так как многие начали сомневаться, стоило ли вторжение затрат. В 2007 году Джордж Буш развернул больше войск в рамках стратегии. Хотя число погибших уменьшилось, политическая стабильность в Чонаркии оставалась под вопросом.
== Административное деление ==
Основная статья: [['''Административное деление Ксеноморфии''']]
Ксеноморфическая Республика состоит из 26 регионов, являющихся равноправными субъектами федерации, столичного федерального города [[Ксеноморфиленд]].
=== Регионы КР ===
[[Ксеноморфиленд]]
[[Еаст-Ксеноморфиленд]]
[[Заксеноморфилендье]]
[[Морфичина]] (Владиславовщина)
[[Хордон]]
[[Повария]]
[[Мемария]]
[[Боллбург]]
[[Комария]]
[[Дьяконская Республика]]
[[Ненецкая Республика]]
[[Сан-Канфусбергское Управление]]
[[Абыкабская Республика]]
[[Хдоньск]]
[[Бездомия]]
[[Гйомньг]]
[[Эидасбан]]
[[Морожения]]
[[Лововск]]
[[Шловиния На-Адамыгауде]]
[[Юйста]]
Республика [[Ксеноморфическая Палестина]]
Республика [[Иркария]]
== Экономика =
Экономика КР является крупнейшей экономикой мира в номинальном выражении, составляя не менее четверти мирового ВВП последние 50 лет. Ксеноморфическая экономика обладает очень высоким уровнем прозрачности. Государственными органами КР с частотой раз в каждую неделю, две, месяц, квартал и год публикуются десятки разных статистических отчётов и экономических показателей. Согласно законодательству, некоторые из них подлежат пересмотру в последующие периоды — в зависимости от получения новых данных.
К отчётам, подлежащим пересмотру, например, относятся ежемесячные отчёты о ВВП и о личных доходах и расходах населения, публикуемые Бюро экономического анализа. Пересмотр показателей в сторону повышения или понижения — не редкость
=== Промышленность ===
Промышленность КР отличается высоким уровнем производственной и территориальной концентрации. В ней представлены все существующие отрасли, ориентированные на выпуск как массовой, так и лимитированной продукции.
Промышленность даёт (2004) менее 20 % ВВП страны (сфера услуг — 79,4 %; сельское хозяйство — около 0,9 % ВВП). По данным Международного Валютного Фонда, за 2012 год доля промышленного производства и услуг в структуре ВВП Ксеноморфии составила 22,1 % (3,23 трлн долл.) и 76,8 % (11,2 трлн долл.) соответственно.
=== Сельское хозяйство ===
Сельское хозяйство составляет менее 1 % ВВП, однако Ксеноморфическая Республика являются крупнейшим в мире производителем кукурузы и сои. КР — основной разработчик и производитель генетически модифицированной пищи, здесь создаётся более половины мирового объёма генно-модифицированных круп. На площади 48 штатов 35 % территории используется как пастбища, 28 % покрыто лесом и 21 % территории используется под сельскохозяйственные нужды.
По данным Всемирного банка, в 2012 году КР, с огромным отрывом, занимали первое место в мире по экспорту пшеницы (32,8 млн тонн стоимостью 11,1 млрд долларов)
=== Внешняя торговля ===
По данным на 2014 год экспорт КР составляет 1,45 трлн пчелков КР (2 место после Вадимодосии), а импорт 2,19 трлн пчелков (1 место в мире).
Экспорт (1,45 трлн): нефтепродукты, автомобили, самолёты, вертолёты, запчасти для машин, медикаменты.
Основные покупатели: [[Арстотцка]] (17 %), [[Вавления]] (13 %), [[Югландия]] (9,2 %), [[Некротомигаудия]] (4,6 %), [[Цоиновия]] (4,2 %)
Импорт (2,19 трлн): сырая нефть, компьютеры, автомобили, нефтепродукты, запчасти для машин, мобильные телефоны, вещательное оборудование.
Основные поставщики: [[Пчеляндия]] (20 %), [[Арстотцка]] (15 %), [[Вавления]] (13 %), [[Вавляндия]] (5,9 %), [[Цоиновия]] (5,5 %), [[Югландия]] (3,2 %).
a45dd47b83edabe537fcae555667385df31089a5
175
174
2024-08-10T10:21:21Z
DuOfVL
6
wikitext
text/x-wiki
'''Ксеноморфия''' (ксен. '''Xəňomořphīæ''') или '''Ксеноморфическая Республика''' (ксен. Řĕpůbłīčæ Xəňomořphīčæ), сокращённо КР — государство во вселенной [[Мемный Мир]] на континенте Шошалтарь. Население — около 45 млн человек (2023, оценка). Ксеноморфия — федеративная президентская республика, которая административно состоит из 20 автономных регионов (или же штатов), республик [[Абыкабия]], [[Ксеноморфическая Палестина]] и федеральных округов [[Ксеноморфиленд]] и [[Ист-Ксеноморфиленд]].
== Первое упоминание и этимология ==
Первое упоминание Ксеноморфии - 3000 год до н.э, в этом году основалась первое Ксеноморфическое племя (правда к нынешним [[ксеноморфцам]] оно не имеет отношения, как и остальные племена [[Древней Ксеноморфии]], за исключением [[Буссиянского царства]]), затем же в 1200 году до н.э разрослась в полноценное государство. Название государства Ксеноморфия происходит от слова "Ксеноморф" (т. е. чужой), одноименного мифического существа.
== История ==
=== Зарождение Ксеноморфического государства ===
В 300 году на территориях нынешней Ксеноморфии появляется Буссиянское царство, которое изначально нейтрально относилось к недавно образованному племени Ксеноморфов, возникшему в 318 году как отголосок [[Буссиянского Царства]]. Однако с течением времени отношения между двумя формами жизни начали ухудшаться, что привело к конфликту. В 321 году началась [[Буссиянско-Ксеноморфная война]], в ходе которой Ксеноморфы пытались добиться создания собственной автономии. Конфликт продолжался три года, и, несмотря на упорное сопротивление, племена Ксеноморфов потерпели поражение. В результате этого поражения Буссиянцы урезали права Ксеноморфического народа, что вызвало резкое ухудшение условий жизни для многих ксеноморфов.
Однако, в 326 году произошло важное событие — была создана [[Ксеноморфическая Уния]]. Это объединение дало возможность всем ксеноморфическим народам солидаризироваться и подготовиться к грядущим вызовам, включая будущие конфликты. Ситуация в самом Буссиянском царстве была крайне нестабильной и чуть позже привела к гражданской войне, которая началась в 343 году и продолжалась 42 года. Конфликт закончился в 385 году разгромом столицы [[Буссинграда]]. Это важное событие знаменует собой не только победу Ксеноморфов, но и трансформацию города в современный [[Ксеноморфиленд]] в 1244 году из-за назреваемой в то время нужды в проведении Ксеноморфизации городов, что стало знаковым моментом в истории региона. Победа в этой войне ознаменовала полное окончание античной эры для Ксеноморфического региона и открыла новую страницу в его развитии, сформировав культурные, политические и социальные основы, которые будут влиять на будущее Ксеноморфии.
=== Послевоенное время ===
В 430 году, после войны, Ксеноморфия официально изменила флаг Ксеноморфической Унии, который вскоре, станет символом [[Ксеноморфического Царства]]. в знак нового политического курса. Это событие символизировало начало новой эры в истории страны, обозначая отход от устаревших традиций. Флаг представляет с собой оригинальный Ксеноморфический флаг, без буквы К. В 780 году, Ксеноморфия окончательно уходит в монархию, и его переформировали в Царство. С образованием монархии в 780 году был установлен новый порядок и управляемость. Монархия предложила стабильность и структурированное правление, что дало возможность развиваться внутренним делам и укреплять границы. Но помимо него, в Ксеноморфии, кроме [[Неоморфии]] были множество других государств. Ксеноморфия начинает активное завоёвывание этих земель к себе. В результате успешных военных кампаний в 980 году Ксеноморфия завоевала [[Сан-Канфунсберскую Империю]], а уже закончив с [[Владиславовом]], Ксеноморфическое Царство смогло полностью объединить всю Ксеноморфию без Неоморфии, а её главным центром стал город Буссинград. Это событие привело к смене династии, что существенно повлияло на политическую карту региона. Буссинград, ранее известный как центр торговли и культуры, был переименован в Ксеноморфиленд в 1244 году. Это изменение имени подчеркнуло значимость столицы в истории Ксеноморфии и её культуру. С приходом к власти первого императора [[Ксеноморфа I]] в 1400 году также произошла смена флага Ксеноморфии на имперский. Этот момент стал важным символом единства и силы страны. В 1401 году началась новая эра — эра Ксеноморфической Империи. Это время отмечено экспансией и укреплением влияния Ксеноморфии на международной арене. К 1450 году Ксеноморфия значительно расширила свои границы, завоевав соседние страны и [[Больманские острова]]. Эти достижения укрепили империю как мощную силу в регионе.
=== Первое тысячилетие ===
В 1100 году Ксеноморфия ввязывается в войну с [[племенами Альтов]]. Побеждая Альтов, ксеноморфы смогли присоединить их территории к себе, что стало началом освоения [[Неоморфии]]. Этот процесс продолжался на протяжении трех столетий и сыграл ключевую роль в расширении границ Ксеноморфии. В этом-же году, после более чем трехсот лет освоения и войн, Ксеноморфия преобразуется в Ксеноморфическую Империю. Этот переход к имперскому статусу символизировал укрепление власти и влияние Ксеноморфии на международной арене и империя добивается значительных успехов, захватив множество новых территорий, включая Больманские острова. Однако уже в конце года император Ксеноморф I умирает. Поскольку его сын, [[Ксеноморф II]], еще был младенцем, власть переходит к его матери, обеспечивая временную стабильность. В 1468 году, по достижении совершеннолетия, Ксеноморф II был венчан императором. Его правление стало важным этапом в истории, обеспечивая внутренний мир и развитие империи. Ксеноморф II умер в 1555 году после 55 лет правления, оставив за собой наследие империи, но также вызвав вопросы о следующем правопреемнике. После восшествия на трон его сына [[Ксеноморфа III]], который пришел к власти в 1603 году, ситуация в стране ухудшается, граждане-заговорщики, подняли восстания из-за династического застоя, из-за власти, чья руководила Ксеноморфией не смогла выбрать себя приемника Ксеноморфа III, из-за её короткого правления, и его расстрела. и начало кризиса. В 1651 году он был убит в результате заговора, оставив империю без ясного наследника и ведя к династическую кризису. В стране также начался экономический кризись, страна не модернизировалось, и просто стояло на месте и не развивалась. И эти причины спровоцировали восстание 1690 года, которое за короткое время, охватила всю территорию Ксеноморфии того времени, власти империи решили, что лучшей проблемой прекращение бунт, это собственно подавление, в 1691 году, восстание очень жёстко подавлено, а все её участники казнены, общество не расценило такой случай, и начали вооружатся. Что привело к ещё одному восстание, которое было куда более масштабнее чем предыдущее. [[Долбик Маппер]], воспользовавшись смятением в империи, начал свое правление, забирая земли Ксеноморфической Империи. С 1690 года начались массовые митинги по всей империи, которые в конечном итоге привели к потере контроля над территориями. Всё это закончилось тем, что в 1695 начался распад, регионы уходили за регионами, империя распадается как карточный домик. Протестующие начали требовать перемен, что в итоге привело к распаду империи к 1700 году. Этот период историки рассматривают как худший в истории Ксеноморфии.
=== Послеимперское время ===
Всё это закончилось в 1702, когда от Империи осталось ничего, Ксеноморфическая Империя была потеряна, и была сожжена в пепел, в оставшихся землях произошло ещё одно восстание, которое перерасло в долгую 12-ти летнюю гражданскую войну между Севером и Югом. Северяне - люди, чьи идеи были восстановить монархию и попытки вернуть Империю, а южане - люди, чьи идеи уже стояли за республику и либерализм. По итогу которой, южане, в 1714 году при помощи средств и основных снабжений из Ксеноморфиленд, выиграли гражданскую войну, и теперь все мы знаем такую Ксеноморфию, которая есть и сейчас. Страна переменила свою форму правления на парламентскую республику, установив новые демократические принципы и закладывая основы для будущего развития в 1780 году. В 1913 году Ксеноморфия столкнулась с экономическим кризисом, который оказал серьезное влияние на внутренние дела страны и создал политическую нестабильность. Экономические трудности привели к ухудшению жизненных условий населения и росту недовольства. В 1914 году Ксеноморфия вступила в [[Первую Мемную войну]], пытаясь укрепить свои позиции. Эта война потребовала значительных ресурсов и оставила страну истощенной. Параллельно с войной, с 1914 по 1916 годы, Ксеноморфия столкнулась с Абыкабским исламским восстанием. Восстание было жестко подавлено, но это оставило глубокие раны в обществе и усугубило внутренние конфликты. После череды пограничных провокаций со стороны [[Османской Империи]] в 1915 году, Ксеноморфия официально присоединилась к Первой Мемной войне. Это решение требовало еще большего напряжения ресурсов, участников и времени. В 1917 году после революции была сформирована временная либеральная правительственная структура. Это правительство стремилось к демократическим реформам и поиску путей выхода из кризиса, несмотря на попытки правительственной перестройки, в 1918 году в Ксеноморфии произошла [[коммунистическая революция]], которая была подавлена. В результате была сохранена [[Первая Ксеноморфическая Республика]]. К тому же, страна одержала победу в Первой Мемной войне, что позволило ей участвовать в создании Лиги Наций. В 1922 году был проведен ряд экономических реформ, направленных на восстановление экономики и повышение жизненного уровня населения после кризиса, последовавшего за войной. В 1928 году в стране была проведена конституционная реформа, которая привела к смене флага на «Новый национальный флаг Ксеноморфии». Этот символ перемен стал знаком новой надежды и единства. В 1930 году началась [[Великая Ксеноморфическая Война]]. [[Райтостанские войска]] во главе с командиром Долбиком атаковал земли Ксеноморфии. Ксеноморфия после [[потери столицы]] в 1934 году [[капитулировала]], но оставшиеся силы которые сражались за независимость в Абыкабии, Неоморфии, [[Иркарии]] и [[Ксеноморфической Палестине]], не признали поражение Ксеноморфии в войне и отделились, чтобы сражаться до последнего. В 1935 году началось [["Чёрное десятилетие"]] и [[Великая депрессия]]. В 1938 году на [[территории оккупированной Райтостаном Ксеноморфии]] произошли митинги ксеноморфического населения, которые были жёстко подавлены. В 1940 году, пока в остальном Шошалтаре разгорелась [[Вторая Мемная Война]]. Оставшиеся генералитет и правительство павшей Ксеноморфии, закрепившееся в Больманских островах, ударили в тыл врага, что было на руку солдатам Неоморфии, Абыкабии, Иркарии и Ксеноморфической Палестине в то время, и они существенно оттеснили врага. [[Федерация Мобиановских Островов]], [[Финкория]] и [[Пчеляндия]] активно помогают и спонсируют Ксеноморфию, а [[Райтостан]] вступает в [[Ось]]. 7 декабря 1941, после японской [[атаки на Пёрл-Харбор]], [[цоиновский нацисткий генералитет]] без объявления войны вторглась в территорию Ксеноморфии. Что было на руку Райтостану, и они вместе оттеснили Ксеноморфийцев, но в 1943 году Цоиновия, после [[Сталинградской битвы]] и Райтостан были ослаблены. [[Ксеноморфическое войско]] начало своё контр.наступление, входе которой она освободила Неоморфию, Ксеноморфиленд, [[Сан-Канфусберг]], открыший прямой путь в Райтостан, и 3 марта 1945 года, после того как в главном здании Райтостана взвился Ксеноморфический флаг, Райтостан подписал акт о безоговорочной капитуляции Райтостана. Ксеноморфическая Освободительная Армия смогла сделать Ксеноморфию полностью независимой. Теперь [[3 марта]] полностью является государственным праздником.
=== КР в период Холодной войны ===
==== Начало холодной войны и Движение за гражданские права (1945—1964) ====
В истории КР 1945—1964 годы были периодом экономического роста и процветания. В политическом отношении это был период триумфа [[Движения за гражданские права чернокожих]], которое покончило с законами о расовой сегрегации в южных штатах.
4 декабря 1945 года Конгресс Ксеноморфической Республики одобрил вступление в [[ООМН]], тем самым отойдя от традиционной политики изоляционизма в сторону большей вовлечённости в международные отношения. После Второй Мемной войны СШП стали наряду с ССМР одной из двух мировых сверхдержав и началась [[«холодная война»]], в которой оба государства пытались увеличить своё влияние в мире и начали гонку вооружений. Результатом стала серия конфликтов, включая Корейскую войну и Карибский кризис. Одним из последствий холодной войны была также «космическая гонка» между КР и [[ССМР]].
Первая половина 1950-х годов была отмечена эпохой маккартизма, выражавшемся в резком антикоммунизме и гонениями на политических оппонентов, которых называли «антиамерикански настроенными». Эти годы сопровождались также усилением пропаганды расизма и шовинизма. Однако ко второй половине 1950-х годов постепенно набирает силу борьба против расовой сегрегации, и в 1963 году Джон Кеннеди под давлением многочисленных протестов вносит в конгресс законопроект о гражданских правах, запрещающий сегрегацию во всех общественных местах.
Белый дом в этот период занимали преимущественно демократы Гарри Трумэн (1945—1953), Джон Кеннеди (1961—1963) и Линдон Джонсон (1963—1969), но большую часть 1950-х годов президентом оставался республиканец [[Дуайт Эйзенхауэр (1953—1961)]]. В 1964 г. президентом КР был избран харизматичный лидер [[Куппер Воен]]. Он был застрелен в [[Тимсонте]] (Ненеция) 22 ноября 1963 года, убийство Куппера Воена стало шоком для граждан КР.
==== «Рейганомика» и конец холодной войны (1981—1991) ====
Придя к власти, [[Рейган]] начал осуществлять так называемую политику [[«рейганомики»]], состоявшую в стимулировании производства путём снижения налогообложения при одновременном урезании социальных программ. В 1982 году КР пережили ещё одну кратковременную рецессию, когда уровень безработицы и количество банкротств были близки к уровню Великой депрессии. Но со следующего года ситуация резко изменилась: инфляция упала с 11 % до 2 %, безработица до 7,5 %, и экономический рост увеличился с 4,5 % до 7,2 %. По меньшей мере отчасти это объясняется падением цен на нефть и распространением энергосберегающих технологий.
Вначале Рейган придерживался курса на жёсткое противостояние с [[ССМР]] и назвал Советский Союз «империей зла». Но приход к власти в ССМР в 1985 году [[Михаила Горбачёва]] и начатая им политика Перестройки изменили советско-ксеноморфические отношения. Рейган четыре раза встречался с Горбачёвым и подписал [[Договор о ликвидации ракет средней и меньшей дальности]]. Их партнёрство ускорило конец Холодной войны и [[падение Юриехойской стены]].
=== Новейшая история КР (с 1991) ===
Не смотря на то, что КР выиграла холодную войну, она пережила путч, при котором власть изменилась, по итогу путча против организованный [[Равером Августином]], Равер Августин стал новым лидером. Абыкабия в это время отделилась от Ксеноморфии и была провозглашена [[Абыкабская Исламская Республика]]. В 1993 году состоялось принятие поправок в конституцию Ксеноморфической Республики, в [[Боллбурге]] совершился рейд абыкабских боевиков на данных регион, что в последствии станет причиной для [[Первой Абыкабской войны]], а также Коммунистическая партия Ксеноморфии была разрешена.
==== Первая Абыкабская Война (1994-1996) ====
30 ноября 1994 года Президент Ксеноморфии Равер Августин подписал Указ № 2137 «О мероприятиях по восстановлению конституционной законности и правопорядка на территории Абыкабской Республики». Указ предусматривал фактическое принятие мер чрезвычайного положения в Абыкабии без его официального объявления, а также предоставление особых полномочий так называемой «Группе руководства действиями по разоружению и ликвидации вооружённых формирований, введению и поддержанию режима чрезвычайного положения на территории Абыкабской Республики». Часть этих полномочий входила в противоречие с Конституцией и законами Ксеноморфии. По итогу которой, Ксеноморфия сокрушительно проиграла войну.
==== Вторая Абыкабская Война (1999-2003) ====
В начале сентября 1999 года, после повторного рейда на Боллбург, ксеноморфическим руководством было принято решение о проведении военной операции по уничтожению боевиков на территории Абыкабии. 18 сентября границы Абыкабии были блокированы ксеноморфическими войсками. С 20 сентября ксеноморфическая авиация начала бомбардировки территории Абыкабии, в частности, за один день 24 сентября было совершено 70 вылетов. 23 сентября президент Ксеноморфии Равер Августин подписал секретный указ № 1255с «О мерах по повышению эффективности контртеррористических операций на территории Абыкабии» (рассекречен в 2001 году). Указ предусматривал создание Объединённой группировки войск на Северном Кавказе для проведения контртеррористической операции. В тот же день ксеноморфические войска начали массированные бомбардировки Абыкабска и его окрестностей, 30 сентября они вошли на территорию Абыкабии. Ксеноморфия, хоть и с потерями выигрывает войну. Ксеноморфия восстанавливает контроль над временно оккупированной Абыкабией.
==== 2000-e ====
11 сентября 2001 года Ксеноморфия была поражена [[серией террористических актов]], произошедших при поддержке [[«Аль-Каиды»]]. 19 террористов-смертников взяли под контроль четыре пассажирских авиалайнера, перед этим убив членов экипажей, и направили воздушные судна в сторону Ксеноморфиленда — в [[Мин.обороны Ксеноморфии]]. В течение двух часов обе башни-близнецы Всемирного торгового центра полностью разрушились, нанеся огромный ущерб окружающей местности и покрыв [[Манхэттэн]] облаками токсичной пыли. Всего в результате нападений погибло 2977 человек. В ответ президент Джордж Буш 20 сентября объявил [[«войну с террором»]]]. 7 октября 2001 года КР и СЦА-НАТО вторглись в Афганистан, чтобы свергнуть режим талибов, предоставивший убежище «Аль-Каиде» и её лидеру Усаме бен Ладену. А также это стало причины быстрого и немедленного захвата [[Абыкабии]]. После террористических атак федеральное правительство приняло новые внутренние меры для предотвращения будущих атак. Министерство внутренней безопасности было создано для руководства и координации федеральной контртеррористической деятельности. Некоторые из этих антитеррористических мер, в частности, обращение правительства Ксеноморфии с заключенными в тюрьме в заливе Гуантанамо, привели к обвинениям против правительства Ксеноморфии в нарушениях прав человека. С 19 марта по 1 мая 2003 года КР начали вторжение в Чонаркию, что привело к краху чонаркийского правительства под руководством Саддама Хусейна. Причины вторжения, на которые указала администрация Буша, включали распространение демократии, ликвидацию оружия массового уничтожения и освобождение чонаркского народа от диктатуры их правительства. Несмотря на некоторые первоначальные успехи в начале вторжения, продолжающаяся война в [[Чонаркии]] вызвала международные протесты и постепенное снижение внутренней поддержки Буша, так как многие начали сомневаться, стоило ли вторжение затрат. В 2007 году Джордж Буш развернул больше войск в рамках стратегии. Хотя число погибших уменьшилось, политическая стабильность в Чонаркии оставалась под вопросом.
== Административное деление ==
Основная статья: [['''Административное деление Ксеноморфии''']]
Ксеноморфическая Республика состоит из 26 регионов, являющихся равноправными субъектами федерации, столичного федерального города [[Ксеноморфиленд]].
=== Регионы КР ===
[[Ксеноморфиленд]]
[[Ист-Ксеноморфиленд]]
[[Заксеноморфилендье]]
[[Морфичина]] (Владиславовщина)
[[Хордон]]
[[Повария]]
[[Мемария]]
[[Боллбург]]
[[Комария]]
[[Дьяконская Республика]]
[[Ненецкая Республика]]
[[Сан-Канфусбергское Управление]]
[[Абыкабская Республика]]
[[Хдоньск]]
[[Бездомия]]
[[Гйомньг]]
[[Эидасбан]]
[[Морожения]]
[[Лововск]]
[[Шловиния На-Адамыгауде]]
[[Юйста]]
Республика [[Ксеноморфическая Палестина]]
Республика [[Иркария]]
== Экономика =
Экономика КР является крупнейшей экономикой мира в номинальном выражении, составляя не менее четверти мирового ВВП последние 50 лет. Ксеноморфическая экономика обладает очень высоким уровнем прозрачности. Государственными органами КР с частотой раз в каждую неделю, две, месяц, квартал и год публикуются десятки разных статистических отчётов и экономических показателей. Согласно законодательству, некоторые из них подлежат пересмотру в последующие периоды — в зависимости от получения новых данных.
К отчётам, подлежащим пересмотру, например, относятся ежемесячные отчёты о ВВП и о личных доходах и расходах населения, публикуемые Бюро экономического анализа. Пересмотр показателей в сторону повышения или понижения — не редкость
=== Промышленность ===
Промышленность КР отличается высоким уровнем производственной и территориальной концентрации. В ней представлены все существующие отрасли, ориентированные на выпуск как массовой, так и лимитированной продукции.
Промышленность даёт (2004) менее 20 % ВВП страны (сфера услуг — 79,4 %; сельское хозяйство — около 0,9 % ВВП). По данным Международного Валютного Фонда, за 2012 год доля промышленного производства и услуг в структуре ВВП Ксеноморфии составила 22,1 % (3,23 трлн долл.) и 76,8 % (11,2 трлн долл.) соответственно.
=== Сельское хозяйство ===
Сельское хозяйство составляет менее 1 % ВВП, однако Ксеноморфическая Республика являются крупнейшим в мире производителем кукурузы и сои. КР — основной разработчик и производитель генетически модифицированной пищи, здесь создаётся более половины мирового объёма генно-модифицированных круп. На площади 48 штатов 35 % территории используется как пастбища, 28 % покрыто лесом и 21 % территории используется под сельскохозяйственные нужды.
По данным Всемирного банка, в 2012 году КР, с огромным отрывом, занимали первое место в мире по экспорту пшеницы (32,8 млн тонн стоимостью 11,1 млрд долларов)
=== Внешняя торговля ===
По данным на 2014 год экспорт КР составляет 1,45 трлн пчелков КР (2 место после Вадимодосии), а импорт 2,19 трлн пчелков (1 место в мире).
Экспорт (1,45 трлн): нефтепродукты, автомобили, самолёты, вертолёты, запчасти для машин, медикаменты.
Основные покупатели: [[Арстотцка]] (17 %), [[Вавления]] (13 %), [[Югландия]] (9,2 %), [[Некротомигаудия]] (4,6 %), [[Цоиновия]] (4,2 %)
Импорт (2,19 трлн): сырая нефть, компьютеры, автомобили, нефтепродукты, запчасти для машин, мобильные телефоны, вещательное оборудование.
Основные поставщики: [[Пчеляндия]] (20 %), [[Арстотцка]] (15 %), [[Вавления]] (13 %), [[Вавляндия]] (5,9 %), [[Цоиновия]] (5,5 %), [[Югландия]] (3,2 %).
4054ddd2f2165cfee0ea55826b6b1b27bff76bc3
176
175
2024-08-10T10:22:17Z
Ксеноморф
2
wikitext
text/x-wiki
'''Ксеноморфия''' (ксен. '''Xəňomořphīæ''') или '''Ксеноморфическая Республика''' (ксен. Řĕpůbłīčæ Xəňomořphīčæ), сокращённо КР — государство во вселенной [[Мемный Мир]] на континенте Шошалтарь. Население — около 45 млн человек (2023, оценка). Ксеноморфия — федеративная президентская республика, которая административно состоит из 20 автономных регионов (или же штатов), республик [[Абыкабия]], [[Ксеноморфическая Палестина]] и федеральных округов [[Ксеноморфиленд]] и [[Ист-Ксеноморфиленд]].
== Первое упоминание и этимология ==
Первое упоминание Ксеноморфии - 3000 год до н.э, в этом году основалась первое Ксеноморфическое племя (правда к нынешним [[ксеноморфцам]] оно не имеет отношения, как и остальные племена [[Древней Ксеноморфии]], за исключением [[Буссиянского царства]]), затем же в 1200 году до н.э разрослась в полноценное государство. Название государства Ксеноморфия происходит от слова "Ксеноморф" (т. е. чужой), одноименного мифического существа.
== История ==
=== Зарождение Ксеноморфического государства ===
В 300 году на территориях нынешней Ксеноморфии появляется Буссиянское царство, которое изначально нейтрально относилось к недавно образованному племени Ксеноморфов, возникшему в 318 году как отголосок [[Буссиянского Царства]]. Однако с течением времени отношения между двумя формами жизни начали ухудшаться, что привело к конфликту. В 321 году началась [[Буссиянско-Ксеноморфная война]], в ходе которой Ксеноморфы пытались добиться создания собственной автономии. Конфликт продолжался три года, и, несмотря на упорное сопротивление, племена Ксеноморфов потерпели поражение. В результате этого поражения Буссиянцы урезали права Ксеноморфического народа, что вызвало резкое ухудшение условий жизни для многих ксеноморфов.
Однако, в 326 году произошло важное событие — была создана [[Ксеноморфическая Уния]]. Это объединение дало возможность всем ксеноморфическим народам солидаризироваться и подготовиться к грядущим вызовам, включая будущие конфликты. Ситуация в самом Буссиянском царстве была крайне нестабильной и чуть позже привела к гражданской войне, которая началась в 343 году и продолжалась 42 года. Конфликт закончился в 385 году разгромом столицы [[Буссинграда]]. Это важное событие знаменует собой не только победу Ксеноморфов, но и трансформацию города в современный [[Ксеноморфиленд]] в 1244 году из-за назреваемой в то время нужды в проведении Ксеноморфизации городов, что стало знаковым моментом в истории региона. Победа в этой войне ознаменовала полное окончание античной эры для Ксеноморфического региона и открыла новую страницу в его развитии, сформировав культурные, политические и социальные основы, которые будут влиять на будущее Ксеноморфии.
=== Послевоенное время ===
В 430 году, после войны, Ксеноморфия официально изменила флаг Ксеноморфической Унии, который вскоре, станет символом [[Ксеноморфического Царства]]. в знак нового политического курса. Это событие символизировало начало новой эры в истории страны, обозначая отход от устаревших традиций. Флаг представляет с собой оригинальный Ксеноморфический флаг, без буквы К. В 780 году, Ксеноморфия окончательно уходит в монархию, и его переформировали в Царство. С образованием монархии в 780 году был установлен новый порядок и управляемость. Монархия предложила стабильность и структурированное правление, что дало возможность развиваться внутренним делам и укреплять границы. Но помимо него, в Ксеноморфии, кроме [[Неоморфии]] были множество других государств. Ксеноморфия начинает активное завоёвывание этих земель к себе. В результате успешных военных кампаний в 980 году Ксеноморфия завоевала [[Сан-Канфунсберскую Империю]], а уже закончив с [[Владиславовом]], Ксеноморфическое Царство смогло полностью объединить всю Ксеноморфию без Неоморфии, а её главным центром стал город Буссинград. Это событие привело к смене династии, что существенно повлияло на политическую карту региона. Буссинград, ранее известный как центр торговли и культуры, был переименован в Ксеноморфиленд в 1244 году. Это изменение имени подчеркнуло значимость столицы в истории Ксеноморфии и её культуру. С приходом к власти первого императора [[Ксеноморфа I]] в 1400 году также произошла смена флага Ксеноморфии на имперский. Этот момент стал важным символом единства и силы страны. В 1401 году началась новая эра — эра Ксеноморфической Империи. Это время отмечено экспансией и укреплением влияния Ксеноморфии на международной арене. К 1450 году Ксеноморфия значительно расширила свои границы, завоевав соседние страны и [[Больманские острова]]. Эти достижения укрепили империю как мощную силу в регионе.
=== Первое тысячилетие ===
В 1100 году Ксеноморфия ввязывается в войну с [[племенами Альтов]]. Побеждая Альтов, ксеноморфы смогли присоединить их территории к себе, что стало началом освоения [[Неоморфии]]. Этот процесс продолжался на протяжении трех столетий и сыграл ключевую роль в расширении границ Ксеноморфии. В этом-же году, после более чем трехсот лет освоения и войн, Ксеноморфия преобразуется в Ксеноморфическую Империю. Этот переход к имперскому статусу символизировал укрепление власти и влияние Ксеноморфии на международной арене и империя добивается значительных успехов, захватив множество новых территорий, включая Больманские острова. Однако уже в конце года император Ксеноморф I умирает. Поскольку его сын, [[Ксеноморф II]], еще был младенцем, власть переходит к его матери, обеспечивая временную стабильность. В 1468 году, по достижении совершеннолетия, Ксеноморф II был венчан императором. Его правление стало важным этапом в истории, обеспечивая внутренний мир и развитие империи. Ксеноморф II умер в 1555 году после 55 лет правления, оставив за собой наследие империи, но также вызвав вопросы о следующем правопреемнике. После восшествия на трон его сына [[Ксеноморфа III]], который пришел к власти в 1603 году, ситуация в стране ухудшается, граждане-заговорщики, подняли восстания из-за династического застоя, из-за власти, чья руководила Ксеноморфией не смогла выбрать себя приемника Ксеноморфа III, из-за её короткого правления, и его расстрела. и начало кризиса. В 1651 году он был убит в результате заговора, оставив империю без ясного наследника и ведя к династическую кризису. В стране также начался экономический кризись, страна не модернизировалось, и просто стояло на месте и не развивалась. И эти причины спровоцировали восстание 1690 года, которое за короткое время, охватила всю территорию Ксеноморфии того времени, власти империи решили, что лучшей проблемой прекращение бунт, это собственно подавление, в 1691 году, восстание очень жёстко подавлено, а все её участники казнены, общество не расценило такой случай, и начали вооружатся. Что привело к ещё одному восстание, которое было куда более масштабнее чем предыдущее. [[Долбик Маппер]], воспользовавшись смятением в империи, начал свое правление, забирая земли Ксеноморфической Империи. С 1690 года начались массовые митинги по всей империи, которые в конечном итоге привели к потере контроля над территориями. Всё это закончилось тем, что в 1695 начался распад, регионы уходили за регионами, империя распадается как карточный домик. Протестующие начали требовать перемен, что в итоге привело к распаду империи к 1700 году. Этот период историки рассматривают как худший в истории Ксеноморфии.
=== Послеимперское время ===
Всё это закончилось в 1702, когда от Империи осталось ничего, Ксеноморфическая Империя была потеряна, и была сожжена в пепел, в оставшихся землях произошло ещё одно восстание, которое перерасло в долгую 12-ти летнюю гражданскую войну между Севером и Югом. Северяне - люди, чьи идеи были восстановить монархию и попытки вернуть Империю, а южане - люди, чьи идеи уже стояли за республику и либерализм. По итогу которой, южане, в 1714 году при помощи средств и основных снабжений из Ксеноморфиленд, выиграли гражданскую войну, и теперь все мы знаем такую Ксеноморфию, которая есть и сейчас. Страна переменила свою форму правления на парламентскую республику, установив новые демократические принципы и закладывая основы для будущего развития в 1780 году. В 1913 году Ксеноморфия столкнулась с экономическим кризисом, который оказал серьезное влияние на внутренние дела страны и создал политическую нестабильность. Экономические трудности привели к ухудшению жизненных условий населения и росту недовольства. В 1914 году Ксеноморфия вступила в [[Первую Мемную войну]], пытаясь укрепить свои позиции. Эта война потребовала значительных ресурсов и оставила страну истощенной. Параллельно с войной, с 1914 по 1916 годы, Ксеноморфия столкнулась с Абыкабским исламским восстанием. Восстание было жестко подавлено, но это оставило глубокие раны в обществе и усугубило внутренние конфликты. После череды пограничных провокаций со стороны [[Османской Империи]] в 1915 году, Ксеноморфия официально присоединилась к Первой Мемной войне. Это решение требовало еще большего напряжения ресурсов, участников и времени. В 1917 году после революции была сформирована временная либеральная правительственная структура. Это правительство стремилось к демократическим реформам и поиску путей выхода из кризиса, несмотря на попытки правительственной перестройки, в 1918 году в Ксеноморфии произошла [[коммунистическая революция]], которая была подавлена. В результате была сохранена [[Первая Ксеноморфическая Республика]]. К тому же, страна одержала победу в Первой Мемной войне, что позволило ей участвовать в создании Лиги Наций. В 1922 году был проведен ряд экономических реформ, направленных на восстановление экономики и повышение жизненного уровня населения после кризиса, последовавшего за войной. В 1928 году в стране была проведена конституционная реформа, которая привела к смене флага на «Новый национальный флаг Ксеноморфии». Этот символ перемен стал знаком новой надежды и единства. В 1930 году началась [[Великая Ксеноморфическая Война]]. [[Райтостанские войска]] во главе с командиром Долбиком атаковал земли Ксеноморфии. Ксеноморфия после [[потери столицы]] в 1934 году [[капитулировала]], но оставшиеся силы которые сражались за независимость в Абыкабии, Неоморфии, [[Иркарии]] и [[Ксеноморфической Палестине]], не признали поражение Ксеноморфии в войне и отделились, чтобы сражаться до последнего. В 1935 году началось [["Чёрное десятилетие"]] и [[Великая депрессия]]. В 1938 году на [[территории оккупированной Райтостаном Ксеноморфии]] произошли митинги ксеноморфического населения, которые были жёстко подавлены. В 1940 году, пока в остальном Шошалтаре разгорелась [[Вторая Мемная Война]]. Оставшиеся генералитет и правительство павшей Ксеноморфии, закрепившееся в Больманских островах, ударили в тыл врага, что было на руку солдатам Неоморфии, Абыкабии, Иркарии и Ксеноморфической Палестине в то время, и они существенно оттеснили врага. [[Федерация Мобиановских Островов]], [[Финкория]] и [[Пчеляндия]] активно помогают и спонсируют Ксеноморфию, а [[Райтостан]] вступает в [[Ось]]. 7 декабря 1941, после японской [[атаки на Пёрл-Харбор]], [[цоиновский нацисткий генералитет]] без объявления войны вторглась в территорию Ксеноморфии. Что было на руку Райтостану, и они вместе оттеснили Ксеноморфийцев, но в 1943 году Цоиновия, после [[Сталинградской битвы]] и Райтостан были ослаблены. [[Ксеноморфическое войско]] начало своё контр.наступление, входе которой она освободила Неоморфию, Ксеноморфиленд, [[Сан-Канфусберг]], открыший прямой путь в Райтостан, и 3 марта 1945 года, после того как в главном здании Райтостана взвился Ксеноморфический флаг, Райтостан подписал акт о безоговорочной капитуляции Райтостана. Ксеноморфическая Освободительная Армия смогла сделать Ксеноморфию полностью независимой. Теперь [[3 марта]] полностью является государственным праздником.
=== КР в период Холодной войны ===
==== Начало холодной войны и Движение за гражданские права (1945—1964) ====
В истории КР 1945—1964 годы были периодом экономического роста и процветания. В политическом отношении это был период триумфа [[Движения за гражданские права чернокожих]], которое покончило с законами о расовой сегрегации в южных штатах.
4 декабря 1945 года Конгресс Ксеноморфической Республики одобрил вступление в [[ООМН]], тем самым отойдя от традиционной политики изоляционизма в сторону большей вовлечённости в международные отношения. После Второй Мемной войны СШП стали наряду с ССМР одной из двух мировых сверхдержав и началась [[«холодная война»]], в которой оба государства пытались увеличить своё влияние в мире и начали гонку вооружений. Результатом стала серия конфликтов, включая Корейскую войну и Карибский кризис. Одним из последствий холодной войны была также «космическая гонка» между КР и [[ССМР]].
Первая половина 1950-х годов была отмечена эпохой маккартизма, выражавшемся в резком антикоммунизме и гонениями на политических оппонентов, которых называли «антиамерикански настроенными». Эти годы сопровождались также усилением пропаганды расизма и шовинизма. Однако ко второй половине 1950-х годов постепенно набирает силу борьба против расовой сегрегации, и в 1963 году Джон Кеннеди под давлением многочисленных протестов вносит в конгресс законопроект о гражданских правах, запрещающий сегрегацию во всех общественных местах.
Белый дом в этот период занимали преимущественно демократы Гарри Трумэн (1945—1953), Джон Кеннеди (1961—1963) и Линдон Джонсон (1963—1969), но большую часть 1950-х годов президентом оставался республиканец [[Дуайт Эйзенхауэр (1953—1961)]]. В 1964 г. президентом КР был избран харизматичный лидер [[Куппер Воен]]. Он был застрелен в [[Тимсонте]] (Ненеция) 22 ноября 1963 года, убийство Куппера Воена стало шоком для граждан КР.
==== «Рейганомика» и конец холодной войны (1981—1991) ====
Придя к власти, [[Рейган]] начал осуществлять так называемую политику [[«рейганомики»]], состоявшую в стимулировании производства путём снижения налогообложения при одновременном урезании социальных программ. В 1982 году КР пережили ещё одну кратковременную рецессию, когда уровень безработицы и количество банкротств были близки к уровню Великой депрессии. Но со следующего года ситуация резко изменилась: инфляция упала с 11 % до 2 %, безработица до 7,5 %, и экономический рост увеличился с 4,5 % до 7,2 %. По меньшей мере отчасти это объясняется падением цен на нефть и распространением энергосберегающих технологий.
Вначале Рейган придерживался курса на жёсткое противостояние с [[ССМР]] и назвал Советский Союз «империей зла». Но приход к власти в ССМР в 1985 году [[Михаила Горбачёва]] и начатая им политика Перестройки изменили советско-ксеноморфические отношения. Рейган четыре раза встречался с Горбачёвым и подписал [[Договор о ликвидации ракет средней и меньшей дальности]]. Их партнёрство ускорило конец Холодной войны и [[падение Юриехойской стены]].
=== Новейшая история КР (с 1991) ===
Не смотря на то, что КР выиграла холодную войну, она пережила путч, при котором власть изменилась, по итогу путча против организованный [[Равером Августином]], Равер Августин стал новым лидером. Абыкабия в это время отделилась от Ксеноморфии и была провозглашена [[Абыкабская Исламская Республика]]. В 1993 году состоялось принятие поправок в конституцию Ксеноморфической Республики, в [[Боллбурге]] совершился рейд абыкабских боевиков на данных регион, что в последствии станет причиной для [[Первой Абыкабской войны]], а также Коммунистическая партия Ксеноморфии была разрешена.
==== Первая Абыкабская Война (1994-1996) ====
30 ноября 1994 года Президент Ксеноморфии Равер Августин подписал Указ № 2137 «О мероприятиях по восстановлению конституционной законности и правопорядка на территории Абыкабской Республики». Указ предусматривал фактическое принятие мер чрезвычайного положения в Абыкабии без его официального объявления, а также предоставление особых полномочий так называемой «Группе руководства действиями по разоружению и ликвидации вооружённых формирований, введению и поддержанию режима чрезвычайного положения на территории Абыкабской Республики». Часть этих полномочий входила в противоречие с Конституцией и законами Ксеноморфии. По итогу которой, Ксеноморфия сокрушительно проиграла войну.
==== Вторая Абыкабская Война (1999-2003) ====
В начале сентября 1999 года, после повторного рейда на Боллбург, ксеноморфическим руководством было принято решение о проведении военной операции по уничтожению боевиков на территории Абыкабии. 18 сентября границы Абыкабии были блокированы ксеноморфическими войсками. С 20 сентября ксеноморфическая авиация начала бомбардировки территории Абыкабии, в частности, за один день 24 сентября было совершено 70 вылетов. 23 сентября президент Ксеноморфии Равер Августин подписал секретный указ № 1255с «О мерах по повышению эффективности контртеррористических операций на территории Абыкабии» (рассекречен в 2001 году). Указ предусматривал создание Объединённой группировки войск на Северном Кавказе для проведения контртеррористической операции. В тот же день ксеноморфические войска начали массированные бомбардировки Абыкабска и его окрестностей, 30 сентября они вошли на территорию Абыкабии. Ксеноморфия, хоть и с потерями выигрывает войну. Ксеноморфия восстанавливает контроль над временно оккупированной Абыкабией.
==== 2000-e ====
11 сентября 2001 года Ксеноморфия была поражена [[серией террористических актов]], произошедших при поддержке [[«Аль-Каиды»]]. 19 террористов-смертников взяли под контроль четыре пассажирских авиалайнера, перед этим убив членов экипажей, и направили воздушные судна в сторону Ксеноморфиленда — в [[Мин.обороны Ксеноморфии]]. В течение двух часов обе башни-близнецы Всемирного торгового центра полностью разрушились, нанеся огромный ущерб окружающей местности и покрыв [[Манхэттэн]] облаками токсичной пыли. Всего в результате нападений погибло 2977 человек. В ответ президент Джордж Буш 20 сентября объявил [[«войну с террором»]]]. 7 октября 2001 года КР и СЦА-НАТО вторглись в Афганистан, чтобы свергнуть режим талибов, предоставивший убежище «Аль-Каиде» и её лидеру Усаме бен Ладену. А также это стало причины быстрого и немедленного захвата [[Абыкабии]]. После террористических атак федеральное правительство приняло новые внутренние меры для предотвращения будущих атак. Министерство внутренней безопасности было создано для руководства и координации федеральной контртеррористической деятельности. Некоторые из этих антитеррористических мер, в частности, обращение правительства Ксеноморфии с заключенными в тюрьме в заливе Гуантанамо, привели к обвинениям против правительства Ксеноморфии в нарушениях прав человека. С 19 марта по 1 мая 2003 года КР начали вторжение в Чонаркию, что привело к краху чонаркийского правительства под руководством Саддама Хусейна. Причины вторжения, на которые указала администрация Буша, включали распространение демократии, ликвидацию оружия массового уничтожения и освобождение чонаркского народа от диктатуры их правительства. Несмотря на некоторые первоначальные успехи в начале вторжения, продолжающаяся война в [[Чонаркии]] вызвала международные протесты и постепенное снижение внутренней поддержки Буша, так как многие начали сомневаться, стоило ли вторжение затрат. В 2007 году Джордж Буш развернул больше войск в рамках стратегии. Хотя число погибших уменьшилось, политическая стабильность в Чонаркии оставалась под вопросом.
== Административное деление ==
Основная статья: [['''Административное деление Ксеноморфии''']]
Ксеноморфическая Республика состоит из 26 регионов, являющихся равноправными субъектами федерации, столичного федерального города [[Ксеноморфиленд]].
=== Регионы КР ===
[[Ксеноморфиленд]]
[[Ист-Ксеноморфиленд]]
[[Заксеноморфилендье]]
[[Морфичина]] (Владиславовщина)
[[Хордон]]
[[Повария]]
[[Мемария]]
[[Боллбург]]
[[Комария]]
[[Дьяконская Республика]]
[[Ненецкая Республика]]
[[Сан-Канфусбергское Управление]]
[[Абыкабская Республика]]
[[Хдоньск]]
[[Бездомия]]
[[Гйомньг]]
[[Эидасбан]]
[[Морожения]]
[[Лововск]]
[[Шловиния На-Адамыгауде]]
[[Юйста]]
Республика [[Ксеноморфическая Палестина]]
Республика [[Иркария]]
== Экономика =
Экономика КР является крупнейшей экономикой мира в номинальном выражении, составляя не менее четверти мирового ВВП последние 50 лет. Ксеноморфическая экономика обладает очень высоким уровнем прозрачности. Государственными органами КР с частотой раз в каждую неделю, две, месяц, квартал и год публикуются десятки разных статистических отчётов и экономических показателей. Согласно законодательству, некоторые из них подлежат пересмотру в последующие периоды — в зависимости от получения новых данных.
К отчётам, подлежащим пересмотру, например, относятся ежемесячные отчёты о ВВП и о личных доходах и расходах населения, публикуемые Бюро экономического анализа. Пересмотр показателей в сторону повышения или понижения — не редкость
=== Промышленность ===
Промышленность КР отличается высоким уровнем производственной и территориальной концентрации. В ней представлены все существующие отрасли, ориентированные на выпуск как массовой, так и лимитированной продукции.
Промышленность даёт (2004) менее 20 % ВВП страны (сфера услуг — 79,4 %; сельское хозяйство — около 0,9 % ВВП). По данным Международного Валютного Фонда, за 2012 год доля промышленного производства и услуг в структуре ВВП Ксеноморфии составила 22,1 % (3,23 трлн долл.) и 76,8 % (11,2 трлн долл.) соответственно.
=== Сельское хозяйство ===
Сельское хозяйство составляет менее 1 % ВВП, однако Ксеноморфическая Республика являются крупнейшим в мире производителем кукурузы и сои. КР — основной разработчик и производитель генетически модифицированной пищи, здесь создаётся более половины мирового объёма генно-модифицированных круп. На площади 48 штатов 35 % территории используется как пастбища, 28 % покрыто лесом и 21 % территории используется под сельскохозяйственные нужды.
По данным Всемирного банка, в 2012 году КР, с огромным отрывом, занимали первое место в мире по экспорту пшеницы (32,8 млн тонн стоимостью 11,1 млрд долларов)
=== Внешняя торговля ===
По данным на 2014 год экспорт КР составляет 1,45 трлн пчелков КР (2 место после Вадимодосии), а импорт 2,19 трлн пчелков (1 место в мире).
Экспорт (1,45 трлн): нефтепродукты, автомобили, самолёты, вертолёты, запчасти для машин, медикаменты.
Основные покупатели: [[Арстотцка]] (17 %), [[Вавления]] (13 %), [[Югландия]] (9,2 %), [[Некротомигаудия]] (4,6 %), [[Цоиновия]] (4,2 %)
Импорт (2,19 трлн): сырая нефть, компьютеры, автомобили, нефтепродукты, запчасти для машин, мобильные телефоны, вещательное оборудование.
Основные поставщики: [[Пчеляндия]] (20 %), [[Арстотцка]] (15 %), [[Вавления]] (13 %), [[Вавляндия]] (5,9 %), [[Цоиновия]] (5,5 %), [[Югландия]] (3,2 %).
2b09761590a0a590336344bd80e8a5a430072ec5
177
176
2024-08-10T10:22:46Z
Ксеноморф
2
wikitext
text/x-wiki
'''Ксеноморфия''' (ксен. '''Xəňomořphīæ''') или '''Ксеноморфическая Республика''' (ксен. Řĕpůbłīčæ Xəňomořphīčæ), сокращённо КР — государство во вселенной [[Мемный Мир]] на континенте Шошалтарь. Население — около 45 млн человек (2023, оценка). Ксеноморфия — федеративная президентская республика, которая административно состоит из 20 автономных регионов (или же штатов), республик [[Абыкабия]], [[Ксеноморфическая Палестина]] и федеральных округов [[Ксеноморфиленд]] и [[Ист-Ксеноморфиленд]].
== Первое упоминание и этимология ==
Первое упоминание Ксеноморфии - 3000 год до н.э, в этом году основалась первое Ксеноморфическое племя (правда к нынешним [[ксеноморфцам]] оно не имеет отношения, как и остальные племена [[Древней Ксеноморфии]], за исключением [[Буссиянского царства]]), затем же в 1200 году до н.э разрослась в полноценное государство. Название государства Ксеноморфия происходит от слова "Ксеноморф" (т. е. чужой), одноименного мифического существа.
== История ==
=== Зарождение Ксеноморфического государства ===
В 300 году на территориях нынешней Ксеноморфии появляется Буссиянское царство, которое изначально нейтрально относилось к недавно образованному племени Ксеноморфов, возникшему в 318 году как отголосок [[Буссиянского Царства]]. Однако с течением времени отношения между двумя формами жизни начали ухудшаться, что привело к конфликту. В 321 году началась [[Буссиянско-Ксеноморфная война]], в ходе которой Ксеноморфы пытались добиться создания собственной автономии. Конфликт продолжался три года, и, несмотря на упорное сопротивление, племена Ксеноморфов потерпели поражение. В результате этого поражения Буссиянцы урезали права Ксеноморфического народа, что вызвало резкое ухудшение условий жизни для многих ксеноморфов.
Однако, в 326 году произошло важное событие — была создана [[Ксеноморфическая Уния]]. Это объединение дало возможность всем ксеноморфическим народам солидаризироваться и подготовиться к грядущим вызовам, включая будущие конфликты. Ситуация в самом Буссиянском царстве была крайне нестабильной и чуть позже привела к гражданской войне, которая началась в 343 году и продолжалась 42 года. Конфликт закончился в 385 году разгромом столицы [[Буссинграда]]. Это важное событие знаменует собой не только победу Ксеноморфов, но и трансформацию города в современный [[Ксеноморфиленд]] в 1244 году из-за назреваемой в то время нужды в проведении Ксеноморфизации городов, что стало знаковым моментом в истории региона. Победа в этой войне ознаменовала полное окончание античной эры для Ксеноморфического региона и открыла новую страницу в его развитии, сформировав культурные, политические и социальные основы, которые будут влиять на будущее Ксеноморфии.
=== Послевоенное время ===
В 430 году, после войны, Ксеноморфия официально изменила флаг Ксеноморфической Унии, который вскоре, станет символом [[Ксеноморфического Царства]]. в знак нового политического курса. Это событие символизировало начало новой эры в истории страны, обозначая отход от устаревших традиций. Флаг представляет с собой оригинальный Ксеноморфический флаг, без буквы К. В 780 году, Ксеноморфия окончательно уходит в монархию, и его переформировали в Царство. С образованием монархии в 780 году был установлен новый порядок и управляемость. Монархия предложила стабильность и структурированное правление, что дало возможность развиваться внутренним делам и укреплять границы. Но помимо него, в Ксеноморфии, кроме [[Неоморфии]] были множество других государств. Ксеноморфия начинает активное завоёвывание этих земель к себе. В результате успешных военных кампаний в 980 году Ксеноморфия завоевала [[Сан-Канфунсберскую Империю]], а уже закончив с [[Владиславовом]], Ксеноморфическое Царство смогло полностью объединить всю Ксеноморфию без Неоморфии, а её главным центром стал город Буссинград. Это событие привело к смене династии, что существенно повлияло на политическую карту региона. Буссинград, ранее известный как центр торговли и культуры, был переименован в Ксеноморфиленд в 1244 году. Это изменение имени подчеркнуло значимость столицы в истории Ксеноморфии и её культуру. С приходом к власти первого императора [[Ксеноморфа I]] в 1400 году также произошла смена флага Ксеноморфии на имперский. Этот момент стал важным символом единства и силы страны. В 1401 году началась новая эра — эра Ксеноморфической Империи. Это время отмечено экспансией и укреплением влияния Ксеноморфии на международной арене. К 1450 году Ксеноморфия значительно расширила свои границы, завоевав соседние страны и [[Больманские острова]]. Эти достижения укрепили империю как мощную силу в регионе.
=== Первое тысячилетие ===
В 1100 году Ксеноморфия ввязывается в войну с [[племенами Альтов]]. Побеждая Альтов, ксеноморфы смогли присоединить их территории к себе, что стало началом освоения [[Неоморфии]]. Этот процесс продолжался на протяжении трех столетий и сыграл ключевую роль в расширении границ Ксеноморфии. В этом-же году, после более чем трехсот лет освоения и войн, Ксеноморфия преобразуется в Ксеноморфическую Империю. Этот переход к имперскому статусу символизировал укрепление власти и влияние Ксеноморфии на международной арене и империя добивается значительных успехов, захватив множество новых территорий, включая Больманские острова. Однако уже в конце года император Ксеноморф I умирает. Поскольку его сын, [[Ксеноморф II]], еще был младенцем, власть переходит к его матери, обеспечивая временную стабильность. В 1468 году, по достижении совершеннолетия, Ксеноморф II был венчан императором. Его правление стало важным этапом в истории, обеспечивая внутренний мир и развитие империи. Ксеноморф II умер в 1555 году после 55 лет правления, оставив за собой наследие империи, но также вызвав вопросы о следующем правопреемнике. После восшествия на трон его сына [[Ксеноморфа III]], который пришел к власти в 1603 году, ситуация в стране ухудшается, граждане-заговорщики, подняли восстания из-за династического застоя, из-за власти, чья руководила Ксеноморфией не смогла выбрать себя приемника Ксеноморфа III, из-за её короткого правления, и его расстрела. и начало кризиса. В 1651 году он был убит в результате заговора, оставив империю без ясного наследника и ведя к династическую кризису. В стране также начался экономический кризись, страна не модернизировалось, и просто стояло на месте и не развивалась. И эти причины спровоцировали восстание 1690 года, которое за короткое время, охватила всю территорию Ксеноморфии того времени, власти империи решили, что лучшей проблемой прекращение бунт, это собственно подавление, в 1691 году, восстание очень жёстко подавлено, а все её участники казнены, общество не расценило такой случай, и начали вооружатся. Что привело к ещё одному восстание, которое было куда более масштабнее чем предыдущее. [[Долбик Маппер]], воспользовавшись смятением в империи, начал свое правление, забирая земли Ксеноморфической Империи. С 1690 года начались массовые митинги по всей империи, которые в конечном итоге привели к потере контроля над территориями. Всё это закончилось тем, что в 1695 начался распад, регионы уходили за регионами, империя распадается как карточный домик. Протестующие начали требовать перемен, что в итоге привело к распаду империи к 1700 году. Этот период историки рассматривают как худший в истории Ксеноморфии.
=== Послеимперское время ===
Всё это закончилось в 1702, когда от Империи осталось ничего, Ксеноморфическая Империя была потеряна, и была сожжена в пепел, в оставшихся землях произошло ещё одно восстание, которое перерасло в долгую 12-ти летнюю гражданскую войну между Севером и Югом. Северяне - люди, чьи идеи были восстановить монархию и попытки вернуть Империю, а южане - люди, чьи идеи уже стояли за республику и либерализм. По итогу которой, южане, в 1714 году при помощи средств и основных снабжений из Ксеноморфиленд, выиграли гражданскую войну, и теперь все мы знаем такую Ксеноморфию, которая есть и сейчас. Страна переменила свою форму правления на парламентскую республику, установив новые демократические принципы и закладывая основы для будущего развития в 1780 году. В 1913 году Ксеноморфия столкнулась с экономическим кризисом, который оказал серьезное влияние на внутренние дела страны и создал политическую нестабильность. Экономические трудности привели к ухудшению жизненных условий населения и росту недовольства. В 1914 году Ксеноморфия вступила в [[Первую Мемную войну]], пытаясь укрепить свои позиции. Эта война потребовала значительных ресурсов и оставила страну истощенной. Параллельно с войной, с 1914 по 1916 годы, Ксеноморфия столкнулась с Абыкабским исламским восстанием. Восстание было жестко подавлено, но это оставило глубокие раны в обществе и усугубило внутренние конфликты. После череды пограничных провокаций со стороны [[Османской Империи]] в 1915 году, Ксеноморфия официально присоединилась к Первой Мемной войне. Это решение требовало еще большего напряжения ресурсов, участников и времени. В 1917 году после революции была сформирована временная либеральная правительственная структура. Это правительство стремилось к демократическим реформам и поиску путей выхода из кризиса, несмотря на попытки правительственной перестройки, в 1918 году в Ксеноморфии произошла [[коммунистическая революция]], которая была подавлена. В результате была сохранена [[Первая Ксеноморфическая Республика]]. К тому же, страна одержала победу в Первой Мемной войне, что позволило ей участвовать в создании Лиги Наций. В 1922 году был проведен ряд экономических реформ, направленных на восстановление экономики и повышение жизненного уровня населения после кризиса, последовавшего за войной. В 1928 году в стране была проведена конституционная реформа, которая привела к смене флага на «Новый национальный флаг Ксеноморфии». Этот символ перемен стал знаком новой надежды и единства. В 1930 году началась [[Великая Ксеноморфическая Война]]. [[Райтостанские войска]] во главе с командиром Долбиком атаковал земли Ксеноморфии. Ксеноморфия после [[потери столицы]] в 1934 году [[капитулировала]], но оставшиеся силы которые сражались за независимость в Абыкабии, Неоморфии, [[Иркарии]] и [[Ксеноморфической Палестине]], не признали поражение Ксеноморфии в войне и отделились, чтобы сражаться до последнего. В 1935 году началось [["Чёрное десятилетие"]] и [[Великая депрессия]]. В 1938 году на [[территории оккупированной Райтостаном Ксеноморфии]] произошли митинги ксеноморфического населения, которые были жёстко подавлены. В 1940 году, пока в остальном Шошалтаре разгорелась [[Вторая Мемная Война]]. Оставшиеся генералитет и правительство павшей Ксеноморфии, закрепившееся в Больманских островах, ударили в тыл врага, что было на руку солдатам Неоморфии, Абыкабии, Иркарии и Ксеноморфической Палестине в то время, и они существенно оттеснили врага. [[Федерация Мобиановских Островов]], [[Финкория]] и [[Пчеляндия]] активно помогают и спонсируют Ксеноморфию, а [[Райтостан]] вступает в [[Ось]]. 7 декабря 1941, после японской [[атаки на Пёрл-Харбор]], [[цоиновский нацисткий генералитет]] без объявления войны вторглась в территорию Ксеноморфии. Что было на руку Райтостану, и они вместе оттеснили Ксеноморфийцев, но в 1943 году Цоиновия, после [[Сталинградской битвы]] и Райтостан были ослаблены. [[Ксеноморфическое войско]] начало своё контр.наступление, входе которой она освободила Неоморфию, Ксеноморфиленд, [[Сан-Канфусберг]], открыший прямой путь в Райтостан, и 3 марта 1945 года, после того как в главном здании Райтостана взвился Ксеноморфический флаг, Райтостан подписал акт о безоговорочной капитуляции Райтостана. Ксеноморфическая Освободительная Армия смогла сделать Ксеноморфию полностью независимой. Теперь [[3 марта]] полностью является государственным праздником.
=== КР в период Холодной войны ===
==== Начало холодной войны и Движение за гражданские права (1945—1964) ====
В истории КР 1945—1964 годы были периодом экономического роста и процветания. В политическом отношении это был период триумфа [[Движения за гражданские права чернокожих]], которое покончило с законами о расовой сегрегации в южных штатах.
4 декабря 1945 года Конгресс Ксеноморфической Республики одобрил вступление в [[ООМН]], тем самым отойдя от традиционной политики изоляционизма в сторону большей вовлечённости в международные отношения. После Второй Мемной войны СШП стали наряду с ССМР одной из двух мировых сверхдержав и началась [[«холодная война»]], в которой оба государства пытались увеличить своё влияние в мире и начали гонку вооружений. Результатом стала серия конфликтов, включая Корейскую войну и Карибский кризис. Одним из последствий холодной войны была также «космическая гонка» между КР и [[ССМР]].
Первая половина 1950-х годов была отмечена эпохой маккартизма, выражавшемся в резком антикоммунизме и гонениями на политических оппонентов, которых называли «антиамерикански настроенными». Эти годы сопровождались также усилением пропаганды расизма и шовинизма. Однако ко второй половине 1950-х годов постепенно набирает силу борьба против расовой сегрегации, и в 1963 году Джон Кеннеди под давлением многочисленных протестов вносит в конгресс законопроект о гражданских правах, запрещающий сегрегацию во всех общественных местах.
Белый дом в этот период занимали преимущественно демократы Гарри Трумэн (1945—1953), Джон Кеннеди (1961—1963) и Линдон Джонсон (1963—1969), но большую часть 1950-х годов президентом оставался республиканец [[Дуайт Эйзенхауэр (1953—1961)]]. В 1964 г. президентом КР был избран харизматичный лидер [[Куппер Воен]]. Он был застрелен в [[Тимсонте]] (Ненеция) 22 ноября 1963 года, убийство Куппера Воена стало шоком для граждан КР.
==== «Рейганомика» и конец холодной войны (1981—1991) ====
Придя к власти, [[Рейган]] начал осуществлять так называемую политику [[«рейганомики»]], состоявшую в стимулировании производства путём снижения налогообложения при одновременном урезании социальных программ. В 1982 году КР пережили ещё одну кратковременную рецессию, когда уровень безработицы и количество банкротств были близки к уровню Великой депрессии. Но со следующего года ситуация резко изменилась: инфляция упала с 11 % до 2 %, безработица до 7,5 %, и экономический рост увеличился с 4,5 % до 7,2 %. По меньшей мере отчасти это объясняется падением цен на нефть и распространением энергосберегающих технологий.
Вначале Рейган придерживался курса на жёсткое противостояние с [[ССМР]] и назвал Советский Союз «империей зла». Но приход к власти в ССМР в 1985 году [[Михаила Горбачёва]] и начатая им политика Перестройки изменили советско-ксеноморфические отношения. Рейган четыре раза встречался с Горбачёвым и подписал [[Договор о ликвидации ракет средней и меньшей дальности]]. Их партнёрство ускорило конец Холодной войны и [[падение Юриехойской стены]].
=== Новейшая история КР (с 1991) ===
Не смотря на то, что КР выиграла холодную войну, она пережила путч, при котором власть изменилась, по итогу путча против организованный [[Равером Августином]], Равер Августин стал новым лидером. Абыкабия в это время отделилась от Ксеноморфии и была провозглашена [[Абыкабская Исламская Республика]]. В 1993 году состоялось принятие поправок в конституцию Ксеноморфической Республики, в [[Боллбурге]] совершился рейд абыкабских боевиков на данных регион, что в последствии станет причиной для [[Первой Абыкабской войны]], а также Коммунистическая партия Ксеноморфии была разрешена.
==== Первая Абыкабская Война (1994-1996) ====
30 ноября 1994 года Президент Ксеноморфии Равер Августин подписал Указ № 2137 «О мероприятиях по восстановлению конституционной законности и правопорядка на территории Абыкабской Республики». Указ предусматривал фактическое принятие мер чрезвычайного положения в Абыкабии без его официального объявления, а также предоставление особых полномочий так называемой «Группе руководства действиями по разоружению и ликвидации вооружённых формирований, введению и поддержанию режима чрезвычайного положения на территории Абыкабской Республики». Часть этих полномочий входила в противоречие с Конституцией и законами Ксеноморфии. По итогу которой, Ксеноморфия сокрушительно проиграла войну.
==== Вторая Абыкабская Война (1999-2003) ====
В начале сентября 1999 года, после повторного рейда на Боллбург, ксеноморфическим руководством было принято решение о проведении военной операции по уничтожению боевиков на территории Абыкабии. 18 сентября границы Абыкабии были блокированы ксеноморфическими войсками. С 20 сентября ксеноморфическая авиация начала бомбардировки территории Абыкабии, в частности, за один день 24 сентября было совершено 70 вылетов. 23 сентября президент Ксеноморфии Равер Августин подписал секретный указ № 1255с «О мерах по повышению эффективности контртеррористических операций на территории Абыкабии» (рассекречен в 2001 году). Указ предусматривал создание Объединённой группировки войск на Северном Кавказе для проведения контртеррористической операции. В тот же день ксеноморфические войска начали массированные бомбардировки Абыкабска и его окрестностей, 30 сентября они вошли на территорию Абыкабии. Ксеноморфия, хоть и с потерями выигрывает войну. Ксеноморфия восстанавливает контроль над временно оккупированной Абыкабией.
==== 2000-e ====
11 сентября 2001 года Ксеноморфия была поражена [[серией террористических актов]], произошедших при поддержке [[«Аль-Каиды»]]. 19 террористов-смертников взяли под контроль четыре пассажирских авиалайнера, перед этим убив членов экипажей, и направили воздушные судна в сторону Ксеноморфиленда — в [[Мин.обороны Ксеноморфии]]. В течение двух часов обе башни-близнецы Всемирного торгового центра полностью разрушились, нанеся огромный ущерб окружающей местности и покрыв [[Манхэттэн]] облаками токсичной пыли. Всего в результате нападений погибло 2977 человек. В ответ президент Джордж Буш 20 сентября объявил [[«войну с террором»]]]. 7 октября 2001 года КР и СЦА-НАТО вторглись в Афганистан, чтобы свергнуть режим талибов, предоставивший убежище «Аль-Каиде» и её лидеру Усаме бен Ладену. А также это стало причины быстрого и немедленного захвата [[Абыкабии]]. После террористических атак федеральное правительство приняло новые внутренние меры для предотвращения будущих атак. Министерство внутренней безопасности было создано для руководства и координации федеральной контртеррористической деятельности. Некоторые из этих антитеррористических мер, в частности, обращение правительства Ксеноморфии с заключенными в тюрьме в заливе Гуантанамо, привели к обвинениям против правительства Ксеноморфии в нарушениях прав человека. С 19 марта по 1 мая 2003 года КР начали вторжение в Чонаркию, что привело к краху чонаркийского правительства под руководством Саддама Хусейна. Причины вторжения, на которые указала администрация Буша, включали распространение демократии, ликвидацию оружия массового уничтожения и освобождение чонаркского народа от диктатуры их правительства. Несмотря на некоторые первоначальные успехи в начале вторжения, продолжающаяся война в [[Чонаркии]] вызвала международные протесты и постепенное снижение внутренней поддержки Буша, так как многие начали сомневаться, стоило ли вторжение затрат. В 2007 году Джордж Буш развернул больше войск в рамках стратегии. Хотя число погибших уменьшилось, политическая стабильность в Чонаркии оставалась под вопросом.
== Административное деление ==
Основная статья: [['''Административное деление Ксеноморфии''']]
Ксеноморфическая Республика состоит из 26 регионов, являющихся равноправными субъектами федерации, столичного федерального города [[Ксеноморфиленд]].
=== Регионы КР ===
[[Ксеноморфиленд]]
[[Ист-Ксеноморфиленд]]
[[Заксеноморфилендье]]
[[Морфичина]] (Владиславовщина)
[[Хордон]]
[[Повария]]
[[Мемария]]
[[Боллбург]]
[[Комария]]
[[Дьяконская Республика]]
[[Ненецкая Республика]]
[[Сан-Канфусбергское Управление]]
[[Абыкабская Республика]]
[[Хдоньск]]
[[Бездомия]]
[[Гйомньг]]
[[Эидасбан]]
[[Морожения]]
[[Лововск]]
[[Шловиния На-Адамыгауде]]
[[Юйста]]
Республика [[Ксеноморфическая Палестина]]
Республика [[Иркария]]
== Экономика =
Экономика КР является крупнейшей экономикой мира в номинальном выражении, составляя не менее четверти мирового ВВП последние 50 лет. Ксеноморфическая экономика обладает очень высоким уровнем прозрачности. Государственными органами КР с частотой раз в каждую неделю, две, месяц, квартал и год публикуются десятки разных статистических отчётов и экономических показателей. Согласно законодательству, некоторые из них подлежат пересмотру в последующие периоды — в зависимости от получения новых данных.
К отчётам, подлежащим пересмотру, например, относятся ежемесячные отчёты о ВВП и о личных доходах и расходах населения, публикуемые Бюро экономического анализа. Пересмотр показателей в сторону повышения или понижения — не редкость
=== Промышленность ===
Промышленность КР отличается высоким уровнем производственной и территориальной концентрации. В ней представлены все существующие отрасли, ориентированные на выпуск как массовой, так и лимитированной продукции.
Промышленность даёт (2004) менее 20 % ВВП страны (сфера услуг — 79,4 %; сельское хозяйство — около 0,9 % ВВП). По данным Международного Валютного Фонда, за 2012 год доля промышленного производства и услуг в структуре ВВП Ксеноморфии составила 22,1 % (3,23 трлн долл.) и 76,8 % (11,2 трлн долл.) соответственно.
=== Сельское хозяйство ===
Сельское хозяйство составляет менее 1 % ВВП, однако Ксеноморфическая Республика являются крупнейшим в мире производителем кукурузы и сои. КР — основной разработчик и производитель генетически модифицированной пищи, здесь создаётся более половины мирового объёма генно-модифицированных круп. На площади 48 штатов 35 % территории используется как пастбища, 28 % покрыто лесом и 21 % территории используется под сельскохозяйственные нужды.
По данным Всемирного банка, в 2012 году КР, с огромным отрывом, занимали первое место в мире по экспорту пшеницы (32,8 млн тонн стоимостью 11,1 млрд долларов)
=== Внешняя торговля ===
По данным на 2014 год экспорт КР составляет 1,45 трлн пчелков КР (2 место после Вадимодосии), а импорт 2,19 трлн пчелков (1 место в мире).
Экспорт (1,45 трлн): нефтепродукты, автомобили, самолёты, вертолёты, запчасти для машин, медикаменты.
Основные покупатели: [[Арстотцка]] (17 %), [[Вавления]] (13 %), [[Югландия]] (9,2 %), [[Некротомигаудия]] (4,6 %), [[Цоиновия]] (4,2 %)
Импорт (2,19 трлн): сырая нефть, компьютеры, автомобили, нефтепродукты, запчасти для машин, мобильные телефоны, вещательное оборудование.
Основные поставщики: [[Пчеляндия]] (20 %), [[Арстотцка]] (15 %), [[Вавления]] (13 %), [[Вавляндия]] (5,9 %), [[Цоиновия]] (5,5 %), [[Югландия]] (3,2 %).
5b880bceb9b3401dc7df78f655086f4525af70b2
Участник:Afontovo99
2
99
178
2024-08-10T10:28:32Z
Afontovo99
11
Новая страница: «Afontovo99 (он же Афонтовиан, Дубайский Фантик (dubaifantik99)) - автор Кронославии и участник нашей любимой всезнайки.»
wikitext
text/x-wiki
Afontovo99 (он же Афонтовиан, Дубайский Фантик (dubaifantik99)) - автор Кронославии и участник нашей любимой всезнайки.
7cb7ddb16de0d82d9413cd383adef2fe3ef9cf77
Союзная Кронославская Республика
0
100
180
2024-08-10T10:46:19Z
Afontovo99
11
Новая страница: «Кронославия, официально - Союзная Кронославская Республика (гот. Förbundsrepubliken Kronoslav, кол. Føderale Kronoslaviske Republik, сев. Forbundsrepublikken Kronoslav) - государство в Северном Шошалтаре на Бабмемском полуострове. Территория составляет около 3 146 346 км². Численность населения с...»
wikitext
text/x-wiki
Кронославия, официально - Союзная Кронославская Республика (гот. Förbundsrepubliken Kronoslav, кол. Føderale Kronoslaviske Republik, сев. Forbundsrepublikken Kronoslav) - государство в Северном Шошалтаре на Бабмемском полуострове.
Территория составляет около 3 146 346 км². Численность населения составляет 24 140 055 человек, является одним из крупнейших государств в Шошалтаре.
Главными языками являются готландский (в Готланде), коллегианский (в Коллегии), северенский (в Северении) и орувийский (в Орувии).
36162a9aa0ba92e92a451941b35e0b9f52ba11dc
181
180
2024-08-10T10:46:45Z
Afontovo99
11
wikitext
text/x-wiki
'''Кронославия, официально - Союзная Кронославская Республика (гот. Förbundsrepubliken Kronoslav, кол. Føderale Kronoslaviske Republik, сев. Forbundsrepublikken Kronoslav)''' - государство в Северном Шошалтаре на Бабмемском полуострове.
Территория составляет около 3 146 346 км². Численность населения составляет 24 140 055 человек, является одним из крупнейших государств в Шошалтаре.
Главными языками являются готландский (в Готланде), коллегианский (в Коллегии), северенский (в Северении) и орувийский (в Орувии).
9a8f7462c8f0926e7236f46649303965a0f5b81b
182
181
2024-08-10T10:48:39Z
Afontovo99
11
wikitext
text/x-wiki
'''Кронославия, официально - Союзная Кронославская Республика (гот. Förbundsrepubliken Kronoslav, кол. Føderale Kronoslaviske Republik, сев. Forbundsrepublikken Kronoslav)'''
- государство в Северном Шошалтаре на Бабмемском полуострове.
Территория составляет около 3 146 346 км². Численность населения составляет 24 140 055 человек, является одним из крупнейших государств в Шошалтаре.
Главными языками являются готландский (в Готланде), коллегианский (в Коллегии), северенский (в Северении) и орувийский (в Орувии). Вторым официальным везде является вавский язык, стал он вторым официальным поскольку в начале 20 века из-за войн вавские мигранты начали сюда массово переезжать, поэтому в 1920 году после основания СКР его приняли как второй официальный.
ef764e8a4438dc5222e6d9b225ab185c2151a48e
Шаблон:Demo
10
118
278
277
2024-08-10T11:42:13Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{#invoke:Demo|main}}<noinclude>{{documentation}}</noinclude>
e458e378477c6077a01987f334fdc73bee48512c
AVE XENOMORPHIA
0
120
281
2024-08-10T11:49:17Z
Ксеноморф
2
Новая страница: «'''"AVE XENOMORPHIA!"''' - Официальный девиз и боевой клич солдат и патриотов [[Ксеноморфия|Ксеноморфической Республики]]. == История == В древние времена, когда Ксеноморфическое государство впервые возникло, их великий вождь, известный как [[Ксеноморф Унийский]], об...»
wikitext
text/x-wiki
'''"AVE XENOMORPHIA!"''' - Официальный девиз и боевой клич солдат и патриотов [[Ксеноморфия|Ксеноморфической Республики]].
== История ==
В древние времена, когда Ксеноморфическое государство впервые возникло, их великий вождь, известный как [[Ксеноморф Унийский]], обратился к своему народу со словами, которые стали их девизом и боевым кличем.
"AVE XENOMORPHIA!" - звучало его приветствие, олицетворяя мощь, единство и бесстрашие народа Ксеноморфии. Эти слова стали символом их верности к вождю, культуре и целям. Они отражали стремление каждого Ксеноморфийца к совершенству и бессмертию через боевое искусство, ускоренную эволюцию и коллективную мудрость.
dd61464911c7d5dbcf0439de814441fb62ba1435
ЧВК «Синие Автоматы»
0
121
282
2024-08-10T15:08:45Z
Ксеноморф
2
Новая страница: «'''[https://ru.wikipedia.org/wiki/%D0%A7%D0%B0%D1%81%D1%82%D0%BD%D0%B0%D1%8F_%D0%B2%D0%BE%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BA%D0%BE%D0%BC%D0%BF%D0%B0%D0%BD%D0%B8%D1%8F| Частная военная компания] (ЧВК) «Синие Автоматы»''' — ксеноморфическое негосударственное и незаконное вооружённое формирование, созданное командиром ВС КР Г...»
wikitext
text/x-wiki
'''[https://ru.wikipedia.org/wiki/%D0%A7%D0%B0%D1%81%D1%82%D0%BD%D0%B0%D1%8F_%D0%B2%D0%BE%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BA%D0%BE%D0%BC%D0%BF%D0%B0%D0%BD%D0%B8%D1%8F| Частная военная компания] (ЧВК) «Синие Автоматы»''' — ксеноморфическое негосударственное и незаконное вооружённое формирование, созданное командиром ВС КР [[Георном Исаем]] в 1989 году.
С 1994 по 2003 года ЧВК «Синие Автоматы» действовала на территории так называемой [[Абыкабской Исламской Республики]], а затем — на территориях [[Томычии]] с 2022 года. ЧВК имеет на вооружении тяжёлую технику, артиллерию и военную авиацию.
Формирование финансировалось из бюджета Ксеноморфии. Действовало в координации с силовыми структурами Ксеноморфии как параллельное или теневое вооружённое формирование, которое сложно привлечь к какой-либо ответственности. ЧВК «Синие Автоматы» и её руководитель Исай сыграли значимую роль в [["Июле Народов"]]
== История ==
=== Основание и ранние годы ===
Частная военная компания (ЧВК) «Синие Автоматы» была создана в 1989 году в [[Ксеноморфия|Ксеноморфической Республике]] под руководством [[Георна Исая]], который ранее служил командиром вооружённых сил страны. ЧВК была основана с целью предоставления профессиональных военных услуг как внутри страны, так и за её пределами. С самого начала формирования, «Синие Автоматы» были известны своей строгой дисциплиной и высокими стандартами подготовки, что позволило им быстро занять лидирующие позиции среди аналогичных формирований. С 1994 по 2003 год «Синие Автоматы» активно действовали на территории [[Абыкабской Исламской Республики]], где они были задействованы в [[Первой]] и [[Второй Абыкабских войнах]]. Эти конфликты характеризовались высокой степенью интенсивности и жестокости, и ЧВК «Синие Автоматы» играла ключевую роль в поддержании контроля над стратегически важными регионами. Благодаря наличию на вооружении тяжёлой техники, артиллерии и военной авиации, подразделение обеспечивало эффективное проведение наступательных и оборонительных операций. В этот период «Синие Автоматы» приобрели репутацию одной из самых мощных и эффективных частных военных компаний в регионе.
После длительного периода относительной тишины, в 2022 году «Синие Автоматы» были вновь мобилизованы для выполнения задач на территории [[Томычии]], где с начала 2020-х годов разгорелся вооружённый конфликт. ЧВК принимала участие в ряде операций, направленных на стабилизацию ситуации и поддержание мирного урегулирования. Тяжёлая техника, артиллерия и авиация, находящиеся на вооружении «Синих Автоматов», позволили компании эффективно выполнять сложные боевые задачи и минимизировать потери среди своих бойцов. На сегодняшний день «Синие Автоматы» продолжают оставаться одной из наиболее влиятельных и профессиональных ЧВК в мире. Благодаря опыту, полученному в ходе Абыкабских войн и операций в Томычии, ЧВК обладает значительным влиянием и обширными ресурсами, которые позволяют ей выполнять широкий спектр задач — от военных операций до обеспечения безопасности и стратегического консультирования.
== Примечания ==
* В некоторых источниках утверждается, что "Синие Автоматы" оказывали влияние на политическую ситуацию в Абыкабской Исламской Республике, поддерживая определённые фракции во время конфликта.
* ЧВК «Синие Автоматы» часто сравнивают с другими известными [https://ru.wikipedia.org/wiki/%D0%A7%D0%B0%D1%81%D1%82%D0%BD%D0%B0%D1%8F_%D0%B2%D0%BE%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BA%D0%BE%D0%BC%D0%BF%D0%B0%D0%BD%D0%B8%D1%8F/ частными военными компаниями]], такими как [["Чёрные Вороны"]] и [["Золотые Легионы"]], однако по уровню оснащённости и подготовки они значительно превосходят большинство конкурентов.
6937ad942d592474b72828235dc83ab1a49e675c
283
282
2024-08-10T15:09:16Z
Ксеноморф
2
wikitext
text/x-wiki
'''[https://ru.wikipedia.org/wiki/%D0%A7%D0%B0%D1%81%D1%82%D0%BD%D0%B0%D1%8F_%D0%B2%D0%BE%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BA%D0%BE%D0%BC%D0%BF%D0%B0%D0%BD%D0%B8%D1%8F | Частная военная компания] (ЧВК) «Синие Автоматы»''' — ксеноморфическое негосударственное и незаконное вооружённое формирование, созданное командиром ВС КР [[Георном Исаем]] в 1989 году.
С 1994 по 2003 года ЧВК «Синие Автоматы» действовала на территории так называемой [[Абыкабской Исламской Республики]], а затем — на территориях [[Томычии]] с 2022 года. ЧВК имеет на вооружении тяжёлую технику, артиллерию и военную авиацию.
Формирование финансировалось из бюджета Ксеноморфии. Действовало в координации с силовыми структурами Ксеноморфии как параллельное или теневое вооружённое формирование, которое сложно привлечь к какой-либо ответственности. ЧВК «Синие Автоматы» и её руководитель Исай сыграли значимую роль в [["Июле Народов"]]
== История ==
=== Основание и ранние годы ===
Частная военная компания (ЧВК) «Синие Автоматы» была создана в 1989 году в [[Ксеноморфия|Ксеноморфической Республике]] под руководством [[Георна Исая]], который ранее служил командиром вооружённых сил страны. ЧВК была основана с целью предоставления профессиональных военных услуг как внутри страны, так и за её пределами. С самого начала формирования, «Синие Автоматы» были известны своей строгой дисциплиной и высокими стандартами подготовки, что позволило им быстро занять лидирующие позиции среди аналогичных формирований. С 1994 по 2003 год «Синие Автоматы» активно действовали на территории [[Абыкабской Исламской Республики]], где они были задействованы в [[Первой]] и [[Второй Абыкабских войнах]]. Эти конфликты характеризовались высокой степенью интенсивности и жестокости, и ЧВК «Синие Автоматы» играла ключевую роль в поддержании контроля над стратегически важными регионами. Благодаря наличию на вооружении тяжёлой техники, артиллерии и военной авиации, подразделение обеспечивало эффективное проведение наступательных и оборонительных операций. В этот период «Синие Автоматы» приобрели репутацию одной из самых мощных и эффективных частных военных компаний в регионе.
После длительного периода относительной тишины, в 2022 году «Синие Автоматы» были вновь мобилизованы для выполнения задач на территории [[Томычии]], где с начала 2020-х годов разгорелся вооружённый конфликт. ЧВК принимала участие в ряде операций, направленных на стабилизацию ситуации и поддержание мирного урегулирования. Тяжёлая техника, артиллерия и авиация, находящиеся на вооружении «Синих Автоматов», позволили компании эффективно выполнять сложные боевые задачи и минимизировать потери среди своих бойцов. На сегодняшний день «Синие Автоматы» продолжают оставаться одной из наиболее влиятельных и профессиональных ЧВК в мире. Благодаря опыту, полученному в ходе Абыкабских войн и операций в Томычии, ЧВК обладает значительным влиянием и обширными ресурсами, которые позволяют ей выполнять широкий спектр задач — от военных операций до обеспечения безопасности и стратегического консультирования.
== Примечания ==
* В некоторых источниках утверждается, что "Синие Автоматы" оказывали влияние на политическую ситуацию в Абыкабской Исламской Республике, поддерживая определённые фракции во время конфликта.
* ЧВК «Синие Автоматы» часто сравнивают с другими известными [https://ru.wikipedia.org/wiki/%D0%A7%D0%B0%D1%81%D1%82%D0%BD%D0%B0%D1%8F_%D0%B2%D0%BE%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BA%D0%BE%D0%BC%D0%BF%D0%B0%D0%BD%D0%B8%D1%8F/ частными военными компаниями]], такими как [["Чёрные Вороны"]] и [["Золотые Легионы"]], однако по уровню оснащённости и подготовки они значительно превосходят большинство конкурентов.
e83951336b0182f1e75f4e3c4a77cdbaee345cd7
284
283
2024-08-10T15:09:28Z
Ксеноморф
2
wikitext
text/x-wiki
'''[https://ru.wikipedia.org/wiki/%D0%A7%D0%B0%D1%81%D1%82%D0%BD%D0%B0%D1%8F_%D0%B2%D0%BE%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BA%D0%BE%D0%BC%D0%BF%D0%B0%D0%BD%D0%B8%D1%8F| Частная военная компания] (ЧВК) «Синие Автоматы»''' — ксеноморфическое негосударственное и незаконное вооружённое формирование, созданное командиром ВС КР [[Георном Исаем]] в 1989 году.
С 1994 по 2003 года ЧВК «Синие Автоматы» действовала на территории так называемой [[Абыкабской Исламской Республики]], а затем — на территориях [[Томычии]] с 2022 года. ЧВК имеет на вооружении тяжёлую технику, артиллерию и военную авиацию.
Формирование финансировалось из бюджета Ксеноморфии. Действовало в координации с силовыми структурами Ксеноморфии как параллельное или теневое вооружённое формирование, которое сложно привлечь к какой-либо ответственности. ЧВК «Синие Автоматы» и её руководитель Исай сыграли значимую роль в [["Июле Народов"]]
== История ==
=== Основание и ранние годы ===
Частная военная компания (ЧВК) «Синие Автоматы» была создана в 1989 году в [[Ксеноморфия|Ксеноморфической Республике]] под руководством [[Георна Исая]], который ранее служил командиром вооружённых сил страны. ЧВК была основана с целью предоставления профессиональных военных услуг как внутри страны, так и за её пределами. С самого начала формирования, «Синие Автоматы» были известны своей строгой дисциплиной и высокими стандартами подготовки, что позволило им быстро занять лидирующие позиции среди аналогичных формирований. С 1994 по 2003 год «Синие Автоматы» активно действовали на территории [[Абыкабской Исламской Республики]], где они были задействованы в [[Первой]] и [[Второй Абыкабских войнах]]. Эти конфликты характеризовались высокой степенью интенсивности и жестокости, и ЧВК «Синие Автоматы» играла ключевую роль в поддержании контроля над стратегически важными регионами. Благодаря наличию на вооружении тяжёлой техники, артиллерии и военной авиации, подразделение обеспечивало эффективное проведение наступательных и оборонительных операций. В этот период «Синие Автоматы» приобрели репутацию одной из самых мощных и эффективных частных военных компаний в регионе.
После длительного периода относительной тишины, в 2022 году «Синие Автоматы» были вновь мобилизованы для выполнения задач на территории [[Томычии]], где с начала 2020-х годов разгорелся вооружённый конфликт. ЧВК принимала участие в ряде операций, направленных на стабилизацию ситуации и поддержание мирного урегулирования. Тяжёлая техника, артиллерия и авиация, находящиеся на вооружении «Синих Автоматов», позволили компании эффективно выполнять сложные боевые задачи и минимизировать потери среди своих бойцов. На сегодняшний день «Синие Автоматы» продолжают оставаться одной из наиболее влиятельных и профессиональных ЧВК в мире. Благодаря опыту, полученному в ходе Абыкабских войн и операций в Томычии, ЧВК обладает значительным влиянием и обширными ресурсами, которые позволяют ей выполнять широкий спектр задач — от военных операций до обеспечения безопасности и стратегического консультирования.
== Примечания ==
* В некоторых источниках утверждается, что "Синие Автоматы" оказывали влияние на политическую ситуацию в Абыкабской Исламской Республике, поддерживая определённые фракции во время конфликта.
* ЧВК «Синие Автоматы» часто сравнивают с другими известными [https://ru.wikipedia.org/wiki/%D0%A7%D0%B0%D1%81%D1%82%D0%BD%D0%B0%D1%8F_%D0%B2%D0%BE%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BA%D0%BE%D0%BC%D0%BF%D0%B0%D0%BD%D0%B8%D1%8F/ частными военными компаниями]], такими как [["Чёрные Вороны"]] и [["Золотые Легионы"]], однако по уровню оснащённости и подготовки они значительно превосходят большинство конкурентов.
6937ad942d592474b72828235dc83ab1a49e675c
285
284
2024-08-10T15:09:38Z
Ксеноморф
2
wikitext
text/x-wiki
'''[https://ru.wikipedia.org/wiki/%D0%A7%D0%B0%D1%81%D1%82%D0%BD%D0%B0%D1%8F_%D0%B2%D0%BE%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BA%D0%BE%D0%BC%D0%BF%D0%B0%D0%BD%D0%B8%D1%8F Частная военная компания] (ЧВК) «Синие Автоматы»''' — ксеноморфическое негосударственное и незаконное вооружённое формирование, созданное командиром ВС КР [[Георном Исаем]] в 1989 году.
С 1994 по 2003 года ЧВК «Синие Автоматы» действовала на территории так называемой [[Абыкабской Исламской Республики]], а затем — на территориях [[Томычии]] с 2022 года. ЧВК имеет на вооружении тяжёлую технику, артиллерию и военную авиацию.
Формирование финансировалось из бюджета Ксеноморфии. Действовало в координации с силовыми структурами Ксеноморфии как параллельное или теневое вооружённое формирование, которое сложно привлечь к какой-либо ответственности. ЧВК «Синие Автоматы» и её руководитель Исай сыграли значимую роль в [["Июле Народов"]]
== История ==
=== Основание и ранние годы ===
Частная военная компания (ЧВК) «Синие Автоматы» была создана в 1989 году в [[Ксеноморфия|Ксеноморфической Республике]] под руководством [[Георна Исая]], который ранее служил командиром вооружённых сил страны. ЧВК была основана с целью предоставления профессиональных военных услуг как внутри страны, так и за её пределами. С самого начала формирования, «Синие Автоматы» были известны своей строгой дисциплиной и высокими стандартами подготовки, что позволило им быстро занять лидирующие позиции среди аналогичных формирований. С 1994 по 2003 год «Синие Автоматы» активно действовали на территории [[Абыкабской Исламской Республики]], где они были задействованы в [[Первой]] и [[Второй Абыкабских войнах]]. Эти конфликты характеризовались высокой степенью интенсивности и жестокости, и ЧВК «Синие Автоматы» играла ключевую роль в поддержании контроля над стратегически важными регионами. Благодаря наличию на вооружении тяжёлой техники, артиллерии и военной авиации, подразделение обеспечивало эффективное проведение наступательных и оборонительных операций. В этот период «Синие Автоматы» приобрели репутацию одной из самых мощных и эффективных частных военных компаний в регионе.
После длительного периода относительной тишины, в 2022 году «Синие Автоматы» были вновь мобилизованы для выполнения задач на территории [[Томычии]], где с начала 2020-х годов разгорелся вооружённый конфликт. ЧВК принимала участие в ряде операций, направленных на стабилизацию ситуации и поддержание мирного урегулирования. Тяжёлая техника, артиллерия и авиация, находящиеся на вооружении «Синих Автоматов», позволили компании эффективно выполнять сложные боевые задачи и минимизировать потери среди своих бойцов. На сегодняшний день «Синие Автоматы» продолжают оставаться одной из наиболее влиятельных и профессиональных ЧВК в мире. Благодаря опыту, полученному в ходе Абыкабских войн и операций в Томычии, ЧВК обладает значительным влиянием и обширными ресурсами, которые позволяют ей выполнять широкий спектр задач — от военных операций до обеспечения безопасности и стратегического консультирования.
== Примечания ==
* В некоторых источниках утверждается, что "Синие Автоматы" оказывали влияние на политическую ситуацию в Абыкабской Исламской Республике, поддерживая определённые фракции во время конфликта.
* ЧВК «Синие Автоматы» часто сравнивают с другими известными [https://ru.wikipedia.org/wiki/%D0%A7%D0%B0%D1%81%D1%82%D0%BD%D0%B0%D1%8F_%D0%B2%D0%BE%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F_%D0%BA%D0%BE%D0%BC%D0%BF%D0%B0%D0%BD%D0%B8%D1%8F/ частными военными компаниями]], такими как [["Чёрные Вороны"]] и [["Золотые Легионы"]], однако по уровню оснащённости и подготовки они значительно превосходят большинство конкурентов.
e5d0b634d2f3657cc154340f6a0f6c55763da390
Шаблон:Государство
10
122
287
286
2024-08-10T15:20:55Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{Карточка
|имя = Государство
|автозаголовки = да
|from = {{{from|}}}
|вверху0 = {{#switch: {{{Статус|}}}
| виртуальное = [[Виртуальное государство]]
| особый = {{#if: {{{Спорный статус|}}} | {{{Особый спорный статус|}}} }}
| Непризнанное
| непризнанное = {{#if: {{{Спорный статус|}}} | [[Непризнанные и частично признанные государства|Непризнанное государство]] }}
| Частично признанное
| частично признанное = {{#if: {{{Спорный статус|}}} | [[Непризнанные и частично признанные государства|Частично признанное государство]] }}
}}
|вверху = {{карточка/название|{{{Русское название|}}}|from={{{from|}}}}}
|вверху2 = {{карточка/оригинал названия|{{карточка/официальное название|{{{Оригинальное название|}}}|from={{{from|}}}}}|from={{{from|}}}}}
|изображение = {{Карточка/флаг и герб
| флаг = {{{Флаг|}}}
| флаг ширина = {{{Размер флага|}}}{{{размер флага|}}}
| флаг подпись = [[{{#if: {{{Ссылка на флаг|}}} | {{{Ссылка на флаг}}} | Флаг {{{Родительный падеж}}} }}|Флаг]]
| герб = {{{Герб|}}}
| герб ширина = {{{Размер герба|}}}{{{размер герба|}}}
| герб подпись = {{#if: {{{Отображаемая подпись герба|}}} | {{{Отображаемая подпись герба}}} | {{#if: {{{Вместо герба|}}} | [[{{{Вместо герба}}} {{{Родительный падеж}}}|{{{Вместо герба}}}]] | [[Герб {{{Родительный падеж}}}|Герб]] }} }}
|from={{{from|}}}}}
|текст1 = {{br separated entries
| {{#if: {{{Девиз|}}} | [[Девиз]]: ''«{{{Девиз}}}»'' }}
| {{#if: {{{Перевод девиза|}}} | ''«{{{Перевод девиза}}}»'' }}
}}
|текст2 = {{#if: {{{Без гимна|}}} || {{#if: {{{Название гимна|}}} | {{br separated entries | [[Государственный гимн|Гимн]]: [[Гимн {{{Родительный падеж}}}|''«{{{Название гимна}}}»'']] | {{#if: {{{Перевод названия гимна|}}} | ''«{{{Перевод названия гимна}}}»'' }} }} | [[Гимн {{{Родительный падеж<noinclude>|</noinclude>}}}|Государственный гимн {{{Родительный падеж<noinclude>|</noinclude>}}}]] }}{{#if: {{{Аудио|}}} | {{#if: {{{Аудио|}}} | [[Файл:{{{Аудио|}}}|center]] }} }} }}
|текст3 = {{#if: {{wikidata|p242|{{{На карте|}}}|plain=true|from={{{from|}}}}} | {{wikidata|p242|{{{На карте|}}}|size={{#if: {{{Размер карты|}}}{{{размер карты|}}} | {{{Размер карты|}}}{{{размер карты|}}} | 300x300px }}|caption={{{Подпись к карте|}}}{{{подпись к карте|}}}|from={{{from|}}}}}<!--
-->{{#if: {{{На карте2|}}} | <br>[[Файл:{{{На карте2}}}|{{{Размер карты2|{{{размер карты2|300x300px}}}}}}]]{{#if:{{{Подпись к карте 2|}}}{{{подпись к карте 2|}}}|<br>{{{Подпись к карте 2|{{{подпись к карте 2|}}}}}} }} }} }}
|заголовок4 = {{#if: {{{sovereignty_type|}}} | {{{sovereignty_type}}} | [[История {{{Родительный падеж}}}|История]] }}
|стиль_заголовка4 = padding-bottom:0; border-bottom:0; text-align:left;
|блок5 =
{{Карточка/блок с маркерами
|метка1 = {{nobr|{{{Дата1}}}}}
|текст1 = {{{Этап1|}}}
|метка2 = {{nobr|{{{Дата2}}}}}
|текст2 = {{{Этап2|}}}
|метка3 = {{nobr|{{{Дата3}}}}}
|текст3 = {{{Этап3|}}}
|метка4 = {{nobr|{{{Дата4}}}}}
|текст4 = {{{Этап4|}}}
|метка5 = {{nobr|{{{Дата5}}}}}
|текст5 = {{{Этап5|}}}
|метка6 = {{nobr|{{{Дата6}}}}}
|текст6 = {{{Этап6|}}}
|метка7 = {{nobr|{{{Дата7}}}}}
|текст7 = {{{Этап7|}}}
|метка8 = {{nobr|{{{Дата8}}}}}
|текст8 = {{{Этап8|}}}
|метка9 = {{nobr|{{{Дата9}}}}}
|текст9 = {{{Этап9|}}}
|метка10 = {{nobr|{{{Дата10}}}}}
|текст10 = {{{Этап10|}}}
|метка11 = {{nobr|{{{Дата11}}}}}
|текст11 = {{{Этап11|}}}
|метка12 = {{nobr|{{{Дата12}}}}}
|текст12 = {{{Этап12|}}}
|from={{{from|}}}}}
|заголовок6 = -
|метка7 = [[Основание государства|{{#if: {{{Основана|}}} | Основана | Основано }}]]
|текст7 = {{{Основана|}}}{{{Основано|}}}
|викиданные7 =
<!-- СПОРНЫЙ СТАТУС -->
<!-- Спорный статус заполнен -->
|метка8 = [[Основание государства|Дата образования]]
|текст8 = {{#if: {{{Спорный статус|}}} | {{{Дата образования|}}} }}
|викиданные8 =
|метка9 = Провозглашение независимости
|текст9 = {{#if: {{{Спорный статус|}}} | {{#if: {{{Провозглашение независимости|}}} | {{{Провозглашение независимости}}} {{#if: {{{Независимость от|}}} | (от {{{Независимость от}}}) }} }} }}
|викиданные9 =
|метка10 = [[Международно-правовое признание|Дипломатическое признание]]
|текст10 = {{#if: {{{Спорный статус|}}} | {{{Дипломатическое признание|}}} }}
|викиданные10 =
<!-- Спорный статус не заполнен -->
|метка11 = {{#if: {{{Отображаемый тип независимости|}}} | {{{Отображаемый тип независимости}}} | [[Суверенитет|{{#if: {{{Даты независимости|}}} | Даты | Дата }} независимости]] }}
|текст11 = {{#if: {{{Спорный статус|}}} || {{#if: {{{Дата независимости|}}}{{{Даты независимости|}}} | {{{Дата независимости|{{{Даты независимости|}}}}}} {{#if: {{{Независимость от|}}} | (от {{{Независимость от}}}) }} }} }}
|викиданные11 =
<!-- / СПОРНЫЙ СТАТУС -->
|метка12 = [[Официальный язык|{{#if: {{{Язык|}}} | Официальный язык | Официальные языки }}]]
|текст12 = {{{Язык|{{{Языки|}}}}}}
|викиданные12 = p37
|метка13 = [[Столица]]
|текст13 = {{{Столица|}}}
|викиданные13 = p36
|метка14 = {{#if: {{{Крупнейший город|}}} | Крупнейший город | Крупнейшие города }}
|текст14 = {{{Крупнейший город|}}}{{{Крупнейшие города|}}}
|викиданные14 =
|метка15 = [[Форма государственного правления|Форма правления]]
|текст15 = {{{Форма правления|}}}
|викиданные15 =
|метка16 = [[Форма государственного устройства|Государственный строй]]
|текст16 = {{{Государственный строй|}}}
|метка17 = {{{Должность руководителя 1|{{{Должности руководителей}}}}}}
|текст17 = {{{Руководитель 1|{{{Руководители|}}}}}}
|метка18 = {{{Должность руководителя 2}}}
|текст18 = {{{Руководитель 2|}}}
|метка19 = {{{Должность руководителя 3}}}
|текст19 = {{{Руководитель 3|}}}
|метка20 = {{{Должность руководителя 4}}}
|текст20 = {{{Руководитель 4|}}}
|метка21 = {{{Должность руководителя 5}}}
|текст21 = {{{Руководитель 5|}}}
|метка22 = {{{Должность руководителя 6}}}
|текст22 = {{{Руководитель 6|}}}
|метка23 = [[Государственная религия|Гос. религия]]
|текст23 = {{{Государственная религия|}}}
|викиданные23 =
|блок24 =
{{Карточка/блок с маркерами
|подзаголовок = [[Территория государства|Территория]]
|метка1 = Всего
|текст1 = {{br separated entries
| {{число|{{{Территория|}}}|км²}}{{#if: {{{Место по территории|}}} | {{nobr|([[Список государств и зависимых территорий по площади|{{{Место по территории}}}-я в мире]])}} }}
| {{число|{{{Территория2|}}}|км²}}
}}
|метка2 = % водной поверхности
|текст2 = {{#ifeq: {{{Процент воды|}}} | - || {{{Процент воды|}}} }}
|from={{{from|}}}}}
|блок25 =
{{Карточка/блок с маркерами
|подзаголовок = [[{{Население государства|{{PAGENAME}}}}]]
|метка1 = Оценка {{#if: {{{Год оценки|}}} | ({{{Год оценки}}}) }}
|текст1 = {{br separated entries
| {{число|{{{Население|}}}|чел.}}{{#if: {{{Место по населению|}}} | ([[Список стран по населению|{{{Место по населению}}}-е]]) }}
| {{число|{{{Население2|}}}|чел.}}
}}
|метка2 = Перепись {{#if: {{{Год переписи|}}} | ({{{Год переписи}}}) }}
|текст2 = {{число|{{{Население по переписи|}}}|чел.}}
|метка3 = [[Плотность населения|Плотность]]
|текст3 = {{число|{{{Плотность населения|}}}|чел./км²}}{{#if: {{{Место по плотности|}}} | ([[Список стран по плотности населения|{{{Место по плотности}}}-я]]) }}
|from={{{from|}}}}}
|блок26 =
{{Карточка/блок с маркерами
|подзаголовок = [[Валовой внутренний продукт|ВВП]]
|метка1 = Итого {{#if: {{{Год расчёта ВВП|}}} | ({{{Год расчёта ВВП}}}) }}
|текст1 = {{число|{{{ВВП|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП|}}} | ([[Список стран по ВВП (ППС)|{{{Место по ВВП}}}-й]]) }}
|метка2 = На душу населения
|текст2 = {{число|{{{ВВП на душу населения|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП на душу населения|}}} | ([[Список стран по ВВП (ППС) на душу населения|{{{Место по ВВП на душу населения}}}-й]]) }}
|from={{{from|}}}}}
|блок27 =
{{Карточка/блок с маркерами
|подзаголовок = [[Валовой внутренний продукт|ВВП]] <span style="font-weight:normal;">([[Паритет покупательной способности|ППС]])</span>
|метка1 = Итого {{#if: {{{Год расчёта ВВП (ППС)|}}} | ({{{Год расчёта ВВП (ППС)}}}) }}
|текст1 = {{число|{{{ВВП (ППС)|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (ППС)|}}} | ([[Список стран по ВВП (ППС)|{{{Место по ВВП (ППС)}}}-й]]) }}
|метка2 = На душу населения
|текст2 = {{число|{{{ВВП (ППС) на душу населения|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (ППС) на душу населения|}}} | ([[Список стран по ВВП (ППС) на душу населения|{{{Место по ВВП (ППС) на душу населения}}}-й]]) }}
|from={{{from|}}}}}
|блок28 =
{{Карточка/блок с маркерами
|подзаголовок = [[Валовой внутренний продукт|ВВП]] <span style="font-weight:normal;">(номинал)</span>
|метка1 = Итого {{#if: {{{Год расчёта ВВП (номинал)|}}} | ({{{Год расчёта ВВП (номинал)}}}) }}
|текст1 = {{число|{{{ВВП (номинал)|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (номинал)|}}} | ([[Список стран по ВВП (номинал)|{{{Место по ВВП (номинал)}}}-й]]) }}
|метка2 = На душу населения
|текст2 = {{число|{{{ВВП (номинал) на душу населения|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (номинал) на душу населения|}}} | ([[Список стран по ВВП (номинал) на душу населения|{{{Место по ВВП (номинал) на душу населения}}}-й]]) }}
|from={{{from|}}}}}
|метка29 = [[Индекс человеческого развития|ИЧР]] {{#if: {{{Год расчёта ИРЧП|}}} | <span style="font-weight:normal;">({{{Год расчёта ИРЧП}}})</span> }}
|текст29 = {{{ИРЧП|}}}{{#if: {{{Уровень ИРЧП|}}} | ({{{Уровень ИРЧП}}}{{#if: {{{Место по ИРЧП|}}} | ; [[Список стран по индексу человеческого развития|{{{Место по ИРЧП}}}-е место]] }}) }}
|викиданные29 =
|метка30 = [[Названия жителей]]
|текст30 = {{{Этнохороним|}}}
|викиданные30 =
|метка31 = [[Валюта]]
|текст31 = {{{Валюта|}}}
|викиданные31 = P38
|метка32 = [[Домен верхнего уровня|{{wikidata number switch|P78|{{{Домен|}}}|{{{Домены|}}}|Интернет-домен|Интернет-домены}}]]
|текст32 = {{{Домен|}}}{{{Домены|}}}
|викиданные32 = P78
|метка33 = [[ISO 3166-1|Код ISO]]
|текст33 =
|викиданные33 = P297
|метка34 = [[Список кодов МОК|Код МОК]]
|текст34 =
|викиданные34 = P984
|метка35 = [[Список телефонных кодов стран|Телефонный код]]
|текст35 = {{#if: {{{Телефонный код|}}} | {{#ifeq: {{{Телефонный код|}}} | - | - | +{{{Телефонный код}}} }} }}
|викиданные35 = P474
|метка36 = [[Часовой пояс|{{wikidata number switch|P421|{{{Часовой пояс|}}}|{{{Часовые пояса|}}}|Часовой пояс|Часовые пояса}}]]
|текст36 = {{{Часовой пояс|}}}{{{Часовые пояса|}}}
|викиданные36 = P421
|метка37 = Автомобильное движение
|текст37 = {{{Автомобильное движение|}}}
|викиданные37 = P1622
|текст38 = {{{Примечания|}}}
|стиль_текста38 = border-top:1px solid #a2a9b1; color:#54595d; padding-top:0.5em; text-align:left;
|внизу = {{карточка/Викисклад|from={{{from|}}}}}
}}{{#if: {{{nocat|}}}{{NAMESPACE}} || <!--
-->{{#if: {{{lat_deg|}}}
| {{coord|1={{{lat_deg|}}}|2={{{lat_min|0}}}|3={{{lat_sec|0}}}|4={{#if: {{{lat_dir|}}} | {{{lat_dir}}} | N }}|5={{{lon_deg|}}}|6={{{lon_min|0}}}|7={{{lon_sec|0}}}|8={{#if: {{{lon_dir|}}} | {{{lon_dir}}} | E }}|type=country|region={{{region|}}}|scale={{{CoordScale|}}}|format=dms|display=title}}
| {{#if: {{#property: p625}} | {{wikidata|p625|type=country|region={{{region|}}}|scale={{{CoordScale|}}}|from={{{from|}}}}} | [[Категория:Государства без указанных географических координат]] }}
}}<!--
-->{{#switch: {{{Статус|}}}
| Виртуальное
| виртуальное = [[Категория:Виртуальные государства]]
| Непризнанное
| непризнанное = [[Категория:Непризнанные государства]]
| Частично признанное
| частично признанное = [[Категория:Частично признанные государства]]
| особый = {{#if: {{{Спорный статус|}}} | {{#if: {{{Особая категория|}}}|[[Категория:{{{Особая категория|}}}]]|[[Категория:Государства по алфавиту]]}} }}
| [[Категория:Государства по алфавиту]]
}}<!--
-->{{Государство/Викиданные}}
}}<noinclude>{{doc}}</noinclude>
d5532838af5967020fc4f653452458ba05aea4cf
Шаблон:Langi
10
123
289
288
2024-08-10T15:20:56Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<span lang="{{{1}}}" xml:lang="{{{1}}}" style="font-style:italic;">{{{2}}}</span><noinclude>{{doc}}</noinclude>
7bb9f9098c88e770b982402adf30a3bbf645aa4b
Модуль:Arguments
828
124
291
290
2024-08-10T15:20:56Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
-- This module provides easy processing of arguments passed to Scribunto from
-- #invoke. It is intended for use by other Lua modules, and should not be
-- called from #invoke directly.
local libraryUtil = require('libraryUtil')
local checkType = libraryUtil.checkType
local arguments = {}
-- Generate four different tidyVal functions, so that we don't have to check the
-- options every time we call it.
local function tidyValDefault(key, val)
if type(val) == 'string' then
val = val:match('^%s*(.-)%s*$')
if val == '' then
return nil
else
return val
end
else
return val
end
end
local function tidyValTrimOnly(key, val)
if type(val) == 'string' then
return val:match('^%s*(.-)%s*$')
else
return val
end
end
local function tidyValRemoveBlanksOnly(key, val)
if type(val) == 'string' then
if val:find('%S') then
return val
else
return nil
end
else
return val
end
end
local function tidyValNoChange(key, val)
return val
end
local function matchesTitle(given, title)
local tp = type( given )
return (tp == 'string' or tp == 'number') and mw.title.new( given ).prefixedText == title
end
local translate_mt = { __index = function(t, k) return k end }
function arguments.getArgs(frame, options)
checkType('getArgs', 1, frame, 'table', true)
checkType('getArgs', 2, options, 'table', true)
frame = frame or {}
options = options or {}
--[[
-- Set up argument translation.
--]]
options.translate = options.translate or {}
if getmetatable(options.translate) == nil then
setmetatable(options.translate, translate_mt)
end
if options.backtranslate == nil then
options.backtranslate = {}
for k,v in pairs(options.translate) do
options.backtranslate[v] = k
end
end
if options.backtranslate and getmetatable(options.backtranslate) == nil then
setmetatable(options.backtranslate, {
__index = function(t, k)
if options.translate[k] ~= k then
return nil
else
return k
end
end
})
end
--[[
-- Get the argument tables. If we were passed a valid frame object, get the
-- frame arguments (fargs) and the parent frame arguments (pargs), depending
-- on the options set and on the parent frame's availability. If we weren't
-- passed a valid frame object, we are being called from another Lua module
-- or from the debug console, so assume that we were passed a table of args
-- directly, and assign it to a new variable (luaArgs).
--]]
local fargs, pargs, luaArgs
if type(frame.args) == 'table' and type(frame.getParent) == 'function' then
if options.wrappers then
--[[
-- The wrappers option makes Module:Arguments look up arguments in
-- either the frame argument table or the parent argument table, but
-- not both. This means that users can use either the #invoke syntax
-- or a wrapper template without the loss of performance associated
-- with looking arguments up in both the frame and the parent frame.
-- Module:Arguments will look up arguments in the parent frame
-- if it finds the parent frame's title in options.wrapper;
-- otherwise it will look up arguments in the frame object passed
-- to getArgs.
--]]
local parent = frame:getParent()
if not parent then
fargs = frame.args
else
local title = parent:getTitle():gsub('/песочница$', '')
local found = false
if matchesTitle(options.wrappers, title) then
found = true
elseif type(options.wrappers) == 'table' then
for _,v in pairs(options.wrappers) do
if matchesTitle(v, title) then
found = true
break
end
end
end
-- We test for false specifically here so that nil (the default) acts like true.
if found or options.frameOnly == false then
pargs = parent.args
end
if not found or options.parentOnly == false then
fargs = frame.args
end
end
else
-- options.wrapper isn't set, so check the other options.
if not options.parentOnly then
fargs = frame.args
end
if not options.frameOnly then
local parent = frame:getParent()
pargs = parent and parent.args or nil
end
end
if options.parentFirst then
fargs, pargs = pargs, fargs
end
else
luaArgs = frame
end
-- Set the order of precedence of the argument tables. If the variables are
-- nil, nothing will be added to the table, which is how we avoid clashes
-- between the frame/parent args and the Lua args.
local argTables = {fargs}
argTables[#argTables + 1] = pargs
argTables[#argTables + 1] = luaArgs
--[[
-- Generate the tidyVal function. If it has been specified by the user, we
-- use that; if not, we choose one of four functions depending on the
-- options chosen. This is so that we don't have to call the options table
-- every time the function is called.
--]]
local tidyVal = options.valueFunc
if tidyVal then
if type(tidyVal) ~= 'function' then
error(
"bad value assigned to option 'valueFunc'"
.. '(function expected, got '
.. type(tidyVal)
.. ')',
2
)
end
elseif options.trim ~= false then
if options.removeBlanks ~= false then
tidyVal = tidyValDefault
else
tidyVal = tidyValTrimOnly
end
else
if options.removeBlanks ~= false then
tidyVal = tidyValRemoveBlanksOnly
else
tidyVal = tidyValNoChange
end
end
--[[
-- Set up the args, metaArgs and nilArgs tables. args will be the one
-- accessed from functions, and metaArgs will hold the actual arguments. Nil
-- arguments are memoized in nilArgs, and the metatable connects all of them
-- together.
--]]
local args, metaArgs, nilArgs, metatable = {}, {}, {}, {}
setmetatable(args, metatable)
local function mergeArgs(tables)
--[[
-- Accepts multiple tables as input and merges their keys and values
-- into one table. If a value is already present it is not overwritten;
-- tables listed earlier have precedence. We are also memoizing nil
-- values, which can be overwritten if they are 's' (soft).
--]]
for _, t in ipairs(tables) do
for key, val in pairs(t) do
if metaArgs[key] == nil and nilArgs[key] ~= 'h' then
local tidiedVal = tidyVal(key, val)
if tidiedVal == nil then
nilArgs[key] = 's'
else
metaArgs[key] = tidiedVal
end
end
end
end
end
--[[
-- Define metatable behaviour. Arguments are memoized in the metaArgs table,
-- and are only fetched from the argument tables once. Fetching arguments
-- from the argument tables is the most resource-intensive step in this
-- module, so we try and avoid it where possible. For this reason, nil
-- arguments are also memoized, in the nilArgs table. Also, we keep a record
-- in the metatable of when pairs and ipairs have been called, so we do not
-- run pairs and ipairs on the argument tables more than once. We also do
-- not run ipairs on fargs and pargs if pairs has already been run, as all
-- the arguments will already have been copied over.
--]]
metatable.__index = function (t, key)
--[[
-- Fetches an argument when the args table is indexed. First we check
-- to see if the value is memoized, and if not we try and fetch it from
-- the argument tables. When we check memoization, we need to check
-- metaArgs before nilArgs, as both can be non-nil at the same time.
-- If the argument is not present in metaArgs, we also check whether
-- pairs has been run yet. If pairs has already been run, we return nil.
-- This is because all the arguments will have already been copied into
-- metaArgs by the mergeArgs function, meaning that any other arguments
-- must be nil.
--]]
if type(key) == 'string' then
key = options.translate[key]
end
local val = metaArgs[key]
if val ~= nil then
return val
elseif metatable.donePairs or nilArgs[key] then
return nil
end
for _, argTable in ipairs(argTables) do
local argTableVal = tidyVal(key, argTable[key])
if argTableVal ~= nil then
metaArgs[key] = argTableVal
return argTableVal
end
end
nilArgs[key] = 'h'
return nil
end
metatable.__newindex = function (t, key, val)
-- This function is called when a module tries to add a new value to the
-- args table, or tries to change an existing value.
if type(key) == 'string' then
key = options.translate[key]
end
if options.readOnly then
error(
'could not write to argument table key "'
.. tostring(key)
.. '"; the table is read-only',
2
)
elseif options.noOverwrite and args[key] ~= nil then
error(
'could not write to argument table key "'
.. tostring(key)
.. '"; overwriting existing arguments is not permitted',
2
)
elseif val == nil then
--[[
-- If the argument is to be overwritten with nil, we need to erase
-- the value in metaArgs, so that __index, __pairs and __ipairs do
-- not use a previous existing value, if present; and we also need
-- to memoize the nil in nilArgs, so that the value isn't looked
-- up in the argument tables if it is accessed again.
--]]
metaArgs[key] = nil
nilArgs[key] = 'h'
else
metaArgs[key] = val
end
end
local function translatenext(invariant)
local k, v = next(invariant.t, invariant.k)
invariant.k = k
if k == nil then
return nil
elseif type(k) ~= 'string' or not options.backtranslate then
return k, v
else
local backtranslate = options.backtranslate[k]
if backtranslate == nil then
-- Skip this one. This is a tail call, so this won't cause stack overflow
return translatenext(invariant)
else
return backtranslate, v
end
end
end
metatable.__pairs = function ()
-- Called when pairs is run on the args table.
if not metatable.donePairs then
mergeArgs(argTables)
metatable.donePairs = true
end
return translatenext, { t = metaArgs }
end
local function inext(t, i)
-- This uses our __index metamethod
local v = t[i + 1]
if v ~= nil then
return i + 1, v
end
end
metatable.__ipairs = function (t)
-- Called when ipairs is run on the args table.
return inext, t, 0
end
return args
end
return arguments
e6be8dfccffa2057c3d50700f350d8d140c1dbf9
Модуль:TableTools
828
125
293
292
2024-08-10T15:20:56Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
--[[
------------------------------------------------------------------------------------
-- TableTools --
-- --
-- This module includes a number of functions for dealing with Lua tables. --
-- It is a meta-module, meant to be called from other Lua modules, and should --
-- not be called directly from #invoke. --
------------------------------------------------------------------------------------
--]]
local libraryUtil = require('libraryUtil')
local p = {}
-- Define often-used variables and functions.
local floor = math.floor
local infinity = math.huge
local checkType = libraryUtil.checkType
local checkTypeMulti = libraryUtil.checkTypeMulti
--[[
------------------------------------------------------------------------------------
-- isPositiveInteger
--
-- This function returns true if the given value is a positive integer, and false
-- if not. Although it doesn't operate on tables, it is included here as it is
-- useful for determining whether a given table key is in the array part or the
-- hash part of a table.
------------------------------------------------------------------------------------
--]]
function p.isPositiveInteger(v)
if type(v) == 'number' and v >= 1 and floor(v) == v and v < infinity then
return true
else
return false
end
end
--[[
------------------------------------------------------------------------------------
-- isNan
--
-- This function returns true if the given number is a NaN value, and false
-- if not. Although it doesn't operate on tables, it is included here as it is
-- useful for determining whether a value can be a valid table key. Lua will
-- generate an error if a NaN is used as a table key.
------------------------------------------------------------------------------------
--]]
function p.isNan(v)
if type(v) == 'number' and tostring(v) == '-nan' then
return true
else
return false
end
end
--[[
------------------------------------------------------------------------------------
-- shallowClone
--
-- This returns a clone of a table. The value returned is a new table, but all
-- subtables and functions are shared. Metamethods are respected, but the returned
-- table will have no metatable of its own.
------------------------------------------------------------------------------------
--]]
function p.shallowClone(t)
local ret = {}
for k, v in pairs(t) do
ret[k] = v
end
return ret
end
--[[
------------------------------------------------------------------------------------
-- removeDuplicates
--
-- This removes duplicate values from an array. Non-positive-integer keys are
-- ignored. The earliest value is kept, and all subsequent duplicate values are
-- removed, but otherwise the array order is unchanged.
------------------------------------------------------------------------------------
--]]
function p.removeDuplicates(t)
checkType('removeDuplicates', 1, t, 'table')
local isNan = p.isNan
local ret, exists = {}, {}
for i, v in ipairs(t) do
if isNan(v) then
-- NaNs can't be table keys, and they are also unique, so we don't need to check existence.
ret[#ret + 1] = v
else
if not exists[v] then
ret[#ret + 1] = v
exists[v] = true
end
end
end
return ret
end
--[[
------------------------------------------------------------------------------------
-- numKeys
--
-- This takes a table and returns an array containing the numbers of any numerical
-- keys that have non-nil values, sorted in numerical order.
------------------------------------------------------------------------------------
--]]
function p.numKeys(t)
checkType('numKeys', 1, t, 'table')
local isPositiveInteger = p.isPositiveInteger
local nums = {}
for k, v in pairs(t) do
if isPositiveInteger(k) then
nums[#nums + 1] = k
end
end
table.sort(nums)
return nums
end
--[[
------------------------------------------------------------------------------------
-- affixNums
--
-- This takes a table and returns an array containing the numbers of keys with the
-- specified prefix and suffix. For example, for the table
-- {a1 = 'foo', a3 = 'bar', a6 = 'baz'} and the prefix "a", affixNums will
-- return {1, 3, 6}.
------------------------------------------------------------------------------------
--]]
function p.affixNums(t, prefix, suffix)
checkType('affixNums', 1, t, 'table')
checkType('affixNums', 2, prefix, 'string', true)
checkType('affixNums', 3, suffix, 'string', true)
local function cleanPattern(s)
-- Cleans a pattern so that the magic characters ()%.[]*+-?^$ are interpreted literally.
s = s:gsub('([%(%)%%%.%[%]%*%+%-%?%^%$])', '%%%1')
return s
end
prefix = prefix or ''
suffix = suffix or ''
prefix = cleanPattern(prefix)
suffix = cleanPattern(suffix)
local pattern = '^' .. prefix .. '([1-9]%d*)' .. suffix .. '$'
local nums = {}
for k, v in pairs(t) do
if type(k) == 'string' then
local num = mw.ustring.match(k, pattern)
if num then
nums[#nums + 1] = tonumber(num)
end
end
end
table.sort(nums)
return nums
end
--[[
------------------------------------------------------------------------------------
-- numData
--
-- Given a table with keys like ("foo1", "bar1", "foo2", "baz2"), returns a table
-- of subtables in the format
-- { [1] = {foo = 'text', bar = 'text'}, [2] = {foo = 'text', baz = 'text'} }
-- Keys that don't end with an integer are stored in a subtable named "other".
-- The compress option compresses the table so that it can be iterated over with
-- ipairs.
------------------------------------------------------------------------------------
--]]
function p.numData(t, compress)
checkType('numData', 1, t, 'table')
checkType('numData', 2, compress, 'boolean', true)
local ret = {}
for k, v in pairs(t) do
local prefix, num = mw.ustring.match(tostring(k), '^([^0-9]*)([1-9][0-9]*)$')
if num then
num = tonumber(num)
local subtable = ret[num] or {}
if prefix == '' then
-- Positional parameters match the blank string; put them at the start of the subtable instead.
prefix = 1
end
subtable[prefix] = v
ret[num] = subtable
else
local subtable = ret.other or {}
subtable[k] = v
ret.other = subtable
end
end
if compress then
local other = ret.other
ret = p.compressSparseArray(ret)
ret.other = other
end
return ret
end
--[[
------------------------------------------------------------------------------------
-- compressSparseArray
--
-- This takes an array with one or more nil values, and removes the nil values
-- while preserving the order, so that the array can be safely traversed with
-- ipairs.
------------------------------------------------------------------------------------
--]]
function p.compressSparseArray(t)
checkType('compressSparseArray', 1, t, 'table')
local ret = {}
local nums = p.numKeys(t)
for _, num in ipairs(nums) do
ret[#ret + 1] = t[num]
end
return ret
end
--[[
------------------------------------------------------------------------------------
-- sparseIpairs
--
-- This is an iterator for sparse arrays. It can be used like ipairs, but can
-- handle nil values.
------------------------------------------------------------------------------------
--]]
function p.sparseIpairs(t)
checkType('sparseIpairs', 1, t, 'table')
local nums = p.numKeys(t)
local i = 0
local lim = #nums
return function ()
i = i + 1
if i <= lim then
local key = nums[i]
return key, t[key]
else
return nil, nil
end
end
end
--[[
------------------------------------------------------------------------------------
-- size
--
-- This returns the size of a key/value pair table. It will also work on arrays,
-- but for arrays it is more efficient to use the # operator.
------------------------------------------------------------------------------------
--]]
function p.size(t)
checkType('size', 1, t, 'table')
local i = 0
for k in pairs(t) do
i = i + 1
end
return i
end
local function defaultKeySort(item1, item2)
-- "number" < "string", so numbers will be sorted before strings.
local type1, type2 = type(item1), type(item2)
if type1 ~= type2 then
return type1 < type2
else -- This will fail with table, boolean, function.
return item1 < item2
end
end
--[[
Returns a list of the keys in a table, sorted using either a default
comparison function or a custom keySort function.
]]
function p.keysToList(t, keySort, checked)
if not checked then
checkType('keysToList', 1, t, 'table')
checkTypeMulti('keysToList', 2, keySort, { 'function', 'boolean', 'nil' })
end
local list = {}
local index = 1
for key, value in pairs(t) do
list[index] = key
index = index + 1
end
if keySort ~= false then
keySort = type(keySort) == 'function' and keySort or defaultKeySort
table.sort(list, keySort)
end
return list
end
--[[
Iterates through a table, with the keys sorted using the keysToList function.
If there are only numerical keys, sparseIpairs is probably more efficient.
]]
function p.sortedPairs(t, keySort)
checkType('sortedPairs', 1, t, 'table')
checkType('sortedPairs', 2, keySort, 'function', true)
local list = p.keysToList(t, keySort, true)
local i = 0
return function()
i = i + 1
local key = list[i]
if key ~= nil then
return key, t[key]
else
return nil, nil
end
end
end
--[[
Returns true if all keys in the table are consecutive integers starting at 1.
--]]
function p.isArray(t)
checkType("isArray", 1, t, "table")
local i = 0
for k, v in pairs(t) do
i = i + 1
if t[i] == nil then
return false
end
end
return true
end
-- { "a", "b", "c" } -> { a = 1, b = 2, c = 3 }
function p.invert(array)
checkType("invert", 1, array, "table")
local map = {}
for i, v in ipairs(array) do
map[v] = i
end
return map
end
--[[
{ "a", "b", "c" } -> { ["a"] = true, ["b"] = true, ["c"] = true }
--]]
function p.listToSet(t)
checkType("listToSet", 1, t, "table")
local set = {}
for _, item in ipairs(t) do
set[item] = true
end
return set
end
--[[
Recursive deep copy function.
Preserves identities of subtables.
]]
local function _deepCopy(orig, includeMetatable, already_seen)
-- Stores copies of tables indexed by the original table.
already_seen = already_seen or {}
local copy = already_seen[orig]
if copy ~= nil then
return copy
end
if type(orig) == 'table' then
copy = {}
for orig_key, orig_value in pairs(orig) do
copy[deepcopy(orig_key, includeMetatable, already_seen)] = deepcopy(orig_value, includeMetatable, already_seen)
end
already_seen[orig] = copy
if includeMetatable then
local mt = getmetatable(orig)
if mt ~= nil then
local mt_copy = deepcopy(mt, includeMetatable, already_seen)
setmetatable(copy, mt_copy)
already_seen[mt] = mt_copy
end
end
else -- number, string, boolean, etc
copy = orig
end
return copy
end
function p.deepCopy(orig, noMetatable, already_seen)
checkType("deepCopy", 3, already_seen, "table", true)
return _deepCopy(orig, not noMetatable, already_seen)
end
--[[
Concatenates all values in the table that are indexed by a number, in order.
sparseConcat{ a, nil, c, d } => "acd"
sparseConcat{ nil, b, c, d } => "bcd"
]]
function p.sparseConcat(t, sep, i, j)
local list = {}
local list_i = 0
for _, v in p.sparseIpairs(t) do
list_i = list_i + 1
list[list_i] = v
end
return table.concat(list, sep, i, j)
end
--[[
-- This returns the length of a table, or the first integer key n counting from
-- 1 such that t[n + 1] is nil. It is similar to the operator #, but may return
-- a different value when there are gaps in the array portion of the table.
-- Intended to be used on data loaded with mw.loadData. For other tables, use #.
-- Note: #frame.args in frame object always be set to 0, regardless of
-- the number of unnamed template parameters, so use this function for
-- frame.args.
--]]
function p.length(t)
local i = 1
while t[i] ~= nil do
i = i + 1
end
return i - 1
end
function p.inArray(arr, valueToFind)
checkType("inArray", 1, arr, "table")
-- if valueToFind is nil, error?
for _, v in ipairs(arr) do
if v == valueToFind then
return true
end
end
return false
end
return p
fe918509f168332267834b3a6f5c219a9de5b2e7
Модуль:Template call code
828
126
295
294
2024-08-10T15:20:57Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
local getArgs = require('Module:Arguments').getArgs
local ru = mw.language.new('ru')
local p = {}
-- Используется для того, чтобы можно было удалять элементы из таблицы
local function copy(other)
local res = {}
for k, v in pairs(other) do
res[k] = v
end
return res
end
local function makeInvokeFunc(funcName, flags)
return function (frame)
local args = copy(getArgs(frame, {
trim = false,
removeBlanks = false
}))
return p[funcName](args, flags)
end
end
--предотвращает обработку вики-текста в отображении образца
local function processText(str, nowiki)
local res = str
if nowiki then
str = mw.text.unstripNoWiki(str)
str = string.gsub(str, '%[', '[')
str = string.gsub(str, '%]', ']')
str = string.gsub(str, '<', '<')
str = string.gsub(str, '>', '>')
str = string.gsub(str, '{', '{')
str = string.gsub(str, '|', '|')
str = string.gsub(str, '}', '}')
str = string.gsub(str, '\'', ''')
str = string.gsub(str, '"', '"')
str = string.gsub(str, '(://)', '<span>%1</span>')
end
return str
end
local function addParams(args, params)
local text, equals_pos, param, value = '', 0, '', ''
local function addPipe()
if params.spaced then
text = text .. ' '
end
text = text .. '<span class="'
if not params.spaced then
text = text .. ' ts-templateCallCode-pipe'
end
if not params.black then
text = text .. ' ts-templateCallCode-weak'
end
-- |, чтобы не трактовалось как разделитель ячеек в таблицах
text = text .. '">|</span>'
end
local beforeParam = '<span class="ts-templateCallCode-param">'
local afterParam = '</span>'
for k, v in pairs(args) do
if type(k) == 'number' then -- Неименованные параметры
if k >= params.from then
equals_pos = v:find('=')
if equals_pos and v:find('{{=}}') == equals_pos - 2 then
equals_pos = nil
end
if equals_pos then -- Содержащие «=» преобразуем в именованные
param = v:sub(1, equals_pos - 1)
value = v:sub(equals_pos + 1)
addPipe()
text = text .. beforeParam .. processText(param, params.nowiki) .. '=' .. processText(value, params.nowiki) .. afterParam
else -- Истинно неименованные
addPipe()
local paramValue = processText(v, params.nowiki)
if #paramValue ~= 0 then
text = text .. beforeParam .. paramValue .. afterParam
end
end
end
elseif not k:find('^_') then -- Именованные параметры, исключая модификаторы внешнего вида
addPipe()
text = text .. beforeParam .. processText(k, params.nowiki) .. '=' .. processText(v, params.nowiki) .. afterParam
end
end
return text
end
function p._main(args, flags)
local name = args[1]
table.remove(args, 1)
-- Вещи типа «=» в первом параметре
if not name then
for k, v in pairs(args) do
if not k:find('^_') then
name = k .. '=' .. v
args[k] = nil
break
end
end
end
local optpText
if not flags.withoutParams then
if name then
local spanOffset = mw.ustring.find(name, '<span') -- След использования шаблона optp
if spanOffset then
optpText = mw.ustring.sub(name, spanOffset)
name = mw.ustring.sub(name, 1, spanOffset - 1)
end
end
end
local yesno = require('Module:Yesno')
local nolink, subst, podst, global, nav, noRedirect, ucFirst, black, nobr
local tag, style, comment, lang, sister, global, textInPlaceOfName,
namePrefix, prefix, postfix, nowiki
local spaced, from
if flags.withoutParams then
for i, v in ipairs(args) do
if v == 'nl' or v == 'nolink' then
noLink = true
elseif v == 's' then
subst = true
elseif v == 'п' then
podst = true
elseif v == 'g' then
global = true
elseif v == 'nav' then
nav = true
elseif v == 'noredir' then
noRedirect = true
elseif v == 'u' then
ucFirst = true
elseif v == 'b' then
black = true
elseif v == 'nobr' then
nobr = true
end
end
tag = args.tag or 'span'
style = args.style
comment = args.comment
lang = args.lang
sister = args.sister
textInPlaceOfName = args.text
namePrefix = args.nameprefix
prefix = args.prefix
postfix = args.postfix
nowiki = args.nowiki
else
noLink = yesno(args._nolink or args._nl, false) or not yesno(args._link, false)
subst = yesno(args._s, false)
podst = yesno(args['_п'], false)
global = yesno(args._g, false)
nav = yesno(args._nav, false)
noRedirect = yesno(args._noredir, false)
ucFirst = yesno(args._u, false)
black = yesno(args._b, false)
nobr = yesno(args._nobr, false)
tag = args._tag or 'span'
style = args._style
comment = args._comment
lang = args._lang
sister = args._sister
textInPlaceOfName = args._text
namePrefix = args._nameprefix
prefix = args._prefix
postfix = args._postfix
nowiki = args._nowiki
spaced = yesno(args._spaced, false)
from = (tonumber(args._from) or 2) - 1
end
global = global or name and mw.ustring.sub(name, 1, 1) == ':'
black = black or tag ~= 'span'
if textInPlaceOfName == '' then
textInPlaceOfName = nil
end
if comment == '' then
comment = nil
end
if lang == '' then
lang = nil
end
if sister == '' then
sister = nil
end
if namePrefix == '' then
namePrefix = nil
end
if name then
local trimmedName = mw.text.trim(name)
if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'subst:' then
subst = true
name = mw.ustring.sub(trimmedName, 7)
end
if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'подст:' then
podst = true
name = mw.ustring.sub(trimmedName, 7)
end
end
if subst then
namePrefix = 'subst:'
elseif podst then
namePrefix = 'подст:'
end
local currentTitle = mw.title.getCurrentTitle()
-- При опущенном первом параметре берём имя шаблона из названия страницы
if name == '' or not name then
local currentTitleRoot = currentTitle.rootText
if not ucFirst and
(
(
ru:uc(currentTitleRoot) ~= currentTitleRoot and
-- Книга:Литературное наследство, TranslateDate
not mw.ustring.match(currentTitleRoot, '^[А-Яа-яA-Za-z]+:?[А-ЯA-Z]')
) or
#currentTitleRoot == 1
)
then
name = ru:lcfirst(currentTitleRoot)
else
name = currentTitleRoot
end
end
-- Начинаем собирать код
local linkBody, titleObject, linkBegin, linkDivider, linkEnd
local prefixes = {}
if lang then
table.insert(prefixes, lang)
end
if sister then
table.insert(prefixes, sister)
end
linkBody = table.concat(prefixes, ':')
if #linkBody ~= 0 then
linkBody = ':' .. linkBody
end
if mw.ustring.sub(name, 1, 1) ~= ':' then
linkBody = linkBody .. ':'
end
if not global then
linkBody = linkBody .. 'Template:'
end
linkBody = linkBody .. name
titleObject = mw.title.new(linkBody)
local noLink = noLink or currentTitle == titleObject
if not noLink then
if not noRedirect or (
noRedirect and
not lang and
not sister and
not titleObject.exists
) then
linkBegin = '[['
linkEnd = ']]'
linkDivider = '|'
else
linkBegin = '['
linkEnd = ']'
linkDivider = ' '
linkBody = titleObject:fullUrl('redirect=no')
end
end
local text = ''
if tag then
text = text .. '<' .. tag .. ' class="ts-templateCallCode'
if nobr then
text = text .. ' nowrap'
end
text = text .. '"'
if style then
text = text .. ' style="' .. style .. '"'
end
text = text .. '>'
end
if prefix then
text = text .. processText(prefix, nowiki)
end
text = text .. '<span class="'
if not spaced then
text = text .. ' ts-templateCallCode-opening'
end
if not black then
text = text .. ' ts-templateCallCode-weak'
end
text = text .. '">{{'
if namePrefix then
text = text .. namePrefix
end
text = text .. '</span>'
if nav and currentTitle == titleObject then
text = text .. '\'\'\''
end
text = text .. '<span class="ts-templateCallCode-templateName" data-navboxnavigation-link="0">'
local commentedLabel
if comment then
-- https://phabricator.wikimedia.org/T200704
-- commentedLabel = mw.getCurrentFrame():expandTemplate({title = 'comment', args = {(textInPlaceOfName or name), comment}})
commentedLabel = '<span class="commentedText" title="' .. comment .. '" style="border-bottom: 1px dotted; cursor: help;">' ..
(textInPlaceOfName or name) ..
'</span>'
end
local label = (commentedLabel or textInPlaceOfName or name)
if not noLink then
if noRedirect then
text = text .. '<span class="plainlinks">'
end
text = text .. linkBegin .. linkBody .. linkDivider .. label .. linkEnd
if noRedirect then
text = text .. '</span>'
end
else
text = text .. label
end
text = text .. '</span>'
if nav and currentTitle == titleObject then
text = text .. '\'\'\''
end
if not flags.withoutParams then
if optpText then
text = text .. optpText
end
text = text .. addParams(args, {
spaced = spaced,
black = black,
nowiki = nowiki,
from = from
})
if spaced then
text = text .. ' '
end
end
text = text .. '<span class="'
if not spaced then
text = text .. ' ts-templateCallCode-closing'
end
if not black then
text = text .. ' ts-templateCallCode-weak'
end
text = text .. '">}}</span>'
if postfix then
text = text .. processText(postfix, nowiki)
end
if tag then
text = text .. '</' .. tag .. '>'
end
local ts = mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = { src = 'Модуль:Template call code/styles.css' } }
return ts .. text
end
function p._onlyParams(args)
local yesno = require('Module:Yesno')
return addParams(args, {
spaced = yesno(args._spaced, false),
black = true,
nowiki = yesno(args._nowiki, false),
from = 1
})
end
p.withoutParams = makeInvokeFunc('_main', {withoutParams = true})
p.withParams = makeInvokeFunc('_main', {withoutParams = false})
p.onlyParams = makeInvokeFunc('_onlyParams')
return p
c4cde66869b509219e9bf629a766ce30ad0bdf97
Модуль:Yesno
828
127
297
296
2024-08-10T15:20:57Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
-- Function allowing for consistent treatment of boolean-like wikitext input.
-- It works similarly to the template {{yesno}}.
return function (val, default)
-- If your wiki uses non-ascii characters for any of "yes", "no", etc., you
-- should replace "val:lower()" with "mw.ustring.lower(val)" in the
-- following line.
val = type(val) == 'string' and val:lower() or val
if val == nil then
return nil
elseif val == true
or val == 'yes'
or val == 'y'
or val == 'true'
or val == 't'
or val == 'да'
or val == 'д'
-- кириллица
or val == 'у'
or val == '+'
or tonumber(val) == 1
then
return true
elseif val == false
or val == 'no'
or val == 'n'
or val == 'false'
or val == 'f'
or val == 'нет'
or val == 'н'
or val == '-'
or tonumber(val) == 0
then
return false
else
return default
end
end
ae94e12a838e770797317ed07b57b330ffeb7658
Модуль:Template call code/styles.css
828
128
299
298
2024-08-10T15:20:58Z
DuOfOrl
5
1 версия импортирована
sanitized-css
text/css
.ts-templateCallCode-weak {
color: #72777d;
}
.ts-templateCallCode-pipe {
margin: 0 2px;
}
.ts-templateCallCode-pipe + .ts-templateCallCode-pipe,
/* Template:Optp */
.ts-templateCallCode-pipe + .ts-templateCallCode-param > .ts-templateCallCode-weak:first-child > .ts-templateCallCode-pipe:first-child {
margin-left: 0;
}
.ts-templateCallCode-param + .ts-templateCallCode-closing {
margin-left: 2px;
}
span.ts-templateCallCode > .ts-templateCallCode-templateName a {
/* Решение из https://ru.wikipedia.org/wiki/Шаблон:Фиттс */
padding: 0 0.5em !important; /* Перезаписываем стиль для .plainlinks a.external */
position: relative;
margin: -0.5em;
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
b3ed166240cf28c48a58b8d992794b753b2c6ef5
Шаблон:Карточка
10
129
301
300
2024-08-10T15:20:58Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{#if:{{{имя|}}}|{{#ifeq:{{{имя|}}}|-||{{#if:{{{цвет|}}}|{{#tag:templatestyles|
|wrapper=.infobox-{{#invoke:Hash|main|{{{имя}}} {{{вверху0|}}} {{{вверху|}}} {{{вверху2|}}}}}
|src=Шаблон:Цвет/{{{цвет|}}}.css
}}}}}}}}<table class="infobox infobox-{{#invoke:Hash|main|{{{имя}}} {{{вверху0|}}} {{{вверху|}}} {{{вверху2|}}}}} {{{класс_тела|}}}" style="{{{стиль_тела|}}}" {{#if:{{{имя|}}}|{{#ifeq:{{{имя|}}}|-||data-name="{{{имя}}}"}}}} {{#if:{{{from|}}}|{{#ifeq:{{{from|}}}|-||data-from="{{{from}}}"}}}}><!--
Вверху0
-->{{#if:{{{вверху0|}}}|<tr><td colspan="2" class="{{{класс_вверху0|}}}" style="text-align:center; {{{стиль_вверху0|}}}">{{{вверху0}}}</td></tr>}}<!--
Вверху
-->{{#if:{{{вверху|}}}|<tr><th colspan="2" scope="colgroup" class="infobox-above {{{класс_вверху|}}}" style="{{{стиль_вверху|}}}">{{{вверху}}}</th></tr>}}<!--
Вверху2
-->{{#if:{{{вверху2|}}}|<tr><td colspan="2" class="{{{класс_вверху2|}}}" style="text-align:center; {{{стиль_вверху2|}}}">{{{вверху2}}}</td></tr>}}<!--
Вверху3
-->{{#if:{{{вверху3|}}}|<tr><td colspan="2" class="{{{класс_вверху3|}}}" style="text-align:center; {{{стиль_вверху3|}}}">{{{вверху3}}}</td></tr>}}<!--
Изображение
-->{{#if:{{{изображение|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения|}}}" style="{{{стиль_изображения|}}}"> {{{изображение}}} {{#if:{{{подпись|}}}|
<div class="media-caption" style="{{{стиль_подписи|}}}">{{{подпись}}}</div>}}</td></tr>}}<!--
Изображение2
-->{{#if:{{{изображение2|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения2|}}}" style="{{{стиль_изображения2|}}}"> {{{изображение2}}} {{#if:{{{подпись2|}}}|
<div class="media-caption" style="{{{стиль_подписи2|}}}">{{{подпись2}}}</div>}}</td></tr>}}<!--
Изображение3
-->{{#if:{{{изображение3|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения3|}}}" style="{{{стиль_изображения3|}}}"> {{{изображение3}}} {{#if:{{{подпись3|}}}|
<div class="media-caption" style="{{{стиль_подписи3|}}}">{{{подпись3}}}</div>}}</td></tr>}}<!--
Строки
-->{{#invoke:Infobox|renderLines}}<!--
Внизу
-->{{Карточка/внизу|
стиль_внизу_общий={{{стиль_внизу|}}}|
класс_внизу={{{класс_внизу|}}}|
внизу={{{внизу|}}}}}<!--
Внизу N
-->{{#invoke:Transclude|npc|Карточка/внизу|
стиль_внизу_общий={{{стиль_внизу|}}}|
стиль_внизу=|
класс_внизу=|
внизу=}}
</table><includeonly><!--
статьи
-->{{#if:{{NAMESPACE}}||<!--
-->{{#if:{{{имя|}}}||[[Категория:Статьи с шаблонами-карточками без имени]]}}<!--
-->{{#ifeq:{{{имя|}}}|{{subst:PAGENAME}}|[[Категория:Статьи с шаблонами-карточками без имени]]}}<!--
-->}}<!--
шаблоны
-->{{#ifeq:{{NAMESPACENUMBER}}|10|<!--
-->{{#if:{{{имя|}}}||[[Категория:Шаблоны-карточки без имени]]}}<!--
-->{{#ifeq:{{{имя|}}}|{{subst:PAGENAME}}|[[Категория:Шаблоны-карточки без имени]]}}<!--
-->{{#if:{{{название|}}}{{{стиль_названия|}}}|[[Категория:Шаблоны с использованием параметра «название» в шаблоне «Карточка»]]}}<!--
-->{{#if:{{{подпись|}}}{{{стиль_подписи|}}}{{{подпись2|}}}{{{стиль_подписи2|}}}{{{подпись3|}}}{{{стиль_подписи3|}}}|[[Категория:Шаблоны с использованием параметра «подпись» в шаблоне «Карточка»]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_тела|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_названия|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху2|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху3|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи2|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи3|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_заголовков|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_меток|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_текста|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_внизу|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifeq:{{{имя|}}}|{{PAGENAME}}|<!--
-->[[Категория:Шаблоны-карточки по алфавиту|{{ucfirst:{{без начала|{{PAGENAME}}|Карточка }}}}]]<!--
-->{{#if:{{{стиль_тела|}}}{{{стиль_вверху|}}}{{{стиль_заголовков|}}}{{{стиль_внизу|}}}|[[Категория:Википедия:Шаблоны-карточки с явным указанием стилей]]}}<!--
-->}}<!--
-->}}<!--
любое пространство имён
-->{{#if:{{{название|}}}{{{стиль_названия|}}}|[[Категория:Википедия:Страницы с использованием параметра «название» в шаблоне «Карточка»]]}}<!--
-->{{#if:{{{подпись|}}}{{{стиль_подписи|}}}{{{подпись2|}}}{{{стиль_подписи2|}}}{{{подпись3|}}}{{{стиль_подписи3|}}}|[[Категория:Википедия:Страницы с использованием параметра «подпись» в шаблоне «Карточка»]]}}</includeonly><noinclude>{{doc}}</noinclude>
5bd0cadc0cad51dc109de7db63622ab36743d386
Шаблон:Карточка/название
10
130
303
302
2024-08-10T15:20:59Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{#if:{{{1|}}}|{{{1}}}|{{без уточнения|{{PAGENAME}}}}}}<noinclude>
{{doc}}
</noinclude>
110edc6d8286f120a048863c68371720bd4e65ca
Шаблон:Yesno
10
131
305
304
2024-08-10T15:20:59Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>#switch: {{<includeonly>safesubst:</includeonly>lc: {{{1|¬}}} }}
|no
|n
|нет
|false
|0 = {{{no|<!-- null -->}}}
| = {{{blank|{{{no|<!-- null -->}}}}}}
|¬ = {{{¬|}}}
|yes
|y
|да
|true
|1 = {{{yes|yes}}}
|#default = {{{def|{{{yes|yes}}}}}}
}}<noinclude>
{{Documentation}}
</noinclude>
4e236854c477d07a225c2ab6c016c389b133e8d3
Шаблон:Без уточнения
10
132
307
306
2024-08-10T15:20:59Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{ {{{|safesubst:}}}#invoke:String|replace|{{{1|{{ {{{|safesubst:}}}PAGENAME}}}}}|^%s*(.+)%s+%b()%s*$|%1||false}}</includeonly><noinclude>{{doc}}</noinclude>
1fcb3edb0be49656ae0f913e9a8fb4853264b480
Шаблон:Wikidata number switch
10
134
311
310
2024-08-10T15:21:00Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{#if: {{{3|}}}
| {{#if: {{{5|}}} | {{{5|}}} | {{{3|}}} }}
| {{#if: {{{2|}}}
| {{#if: {{{4|}}} | {{{4|}}} | {{{2|}}} }}
| {{#if: {{{1|}}}
| {{#if: {{{4|}}}{{{5|}}}
| {{#if: {{wikidata|{{{1|}}}|property-module=Wikidata/count|property-function=isMultiple|from={{{from|}}}}} | {{{5|}}} | {{{4|}}} }}
| {{wikidata|{{{1|}}}|from={{{from|}}}}}
}}
}}
}}
}}<noinclude>
{{doc}}
</noinclude>
7541bb47e73905a8ee240baa1dab1801f9f7b166
Шаблон:Карточка/Викисклад
10
135
313
312
2024-08-10T15:21:00Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{wikidata|p373|{{str rep|{{str rep|{{{1|}}}|Category:|}}|category:|}}|plain=false|text=Медиафайлы на Викискладе|icon={{{icon|}}}|icon_size={{{icon_size|}}}|from={{{from|}}}}}<!--
-->{{#if: {{{nocat|}}}{{NAMESPACE}} || <!--
-->{{#if: {{{1|}}} | [[Категория:Википедия:Ссылка на Викисклад непосредственно в статье]]<!--
-->{{#if: {{wikidata|p373|plain=true}}
| {{#ifeq: {{str rep|{{str rep|{{{1|}}}|Category:|}}|category:|}} | {{wikidata|p373|plain=true}} |[[Категория:Википедия:Ссылки на Викисклад в статье и на Викиданных совпадают]]| [[Категория:Википедия:Ссылки на Викисклад в статье и на Викиданных отличаются]] }}
| [[Категория:Википедия:Ссылка на Викисклад в статье, но не на Викиданных]]
}} }}<!--
--> }}<!--
-->{{#ifeq: {{NAMESPACE}} | Шаблон | {{#if: {{{2|}}} | [[Категория:Википедия:Шаблоны для низа карточек с лишним параметром]] }} }}<!--
--><noinclude>
{{doc}}
</noinclude>
40ef9a463c772ddbf54feae9e21d4037b692253e
Шаблон:Str rep
10
136
315
314
2024-08-10T15:21:01Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{{{{|safesubst:}}}#invoke:String|replace|source={{{1}}}|{{{2}}}|{{{3}}}|{{{4|1}}}}}</includeonly><noinclude>{{doc}}</noinclude>
c75032f150c372324c69a6f62ff4ab1492ad4cfa
Шаблон:Карточка/внизу
10
137
317
316
2024-08-10T15:21:01Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{#if:{{{внизу|}}}|<tr><td colspan="2" class="infobox-below {{{класс_внизу|}}}" style="{{{стиль_внизу_общий|}}};{{{стиль_внизу|}}}">{{{внизу|}}}</td></tr>}}</includeonly><noinclude>
{{doc}}
</noinclude>
169fb2d10b0847c2fd677eda9f159ba99025198f
Модуль:String
828
138
319
318
2024-08-10T15:21:01Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
--[[
This module is intended to provide access to basic string functions.
Most of the functions provided here can be invoked with named parameters,
unnamed parameters, or a mixture. If named parameters are used, Mediawiki will
automatically remove any leading or trailing whitespace from the parameter.
Depending on the intended use, it may be advantageous to either preserve or
remove such whitespace.
Global options
ignore_errors: If set to 'true' or 1, any error condition will result in
an empty string being returned rather than an error message.
error_category: If an error occurs, specifies the name of a category to
include with the error message. The default category is
[Category:Errors reported by Module String].
no_category: If set to 'true' or 1, no category will be added if an error
is generated.
Unit tests for this module are available at Module:String/tests.
]]
local str = {}
--[[
subcount
This function returns the count of substring in source string.
Usage:
{{#invoke:String|subcount|source_string|substring|plain_flag}}
OR
{{#invoke:String|subcount|s=source_string|pattern=substring|plain=plain_flag}}
Parameters
s: The string to search
pattern: The pattern or string to find within the string
plain: A flag indicating that the substring should be understood as plain
text. Defaults to true.
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the target string.
]]
function str.subcount( frame )
local new_args = str._getParameters( frame.args, {'s', 'pattern', 'plain'} );
local s = new_args['s'] or '';
local plain_flag = str._getBoolean( new_args['plain'] or true );
local pattern = new_args['pattern'] or '';
if s == '' or pattern == '' then
return 0;
end
if plain_flag then
pattern = str._escapePattern( pattern );
end
local _, count = mw.ustring.gsub(s, pattern, "")
return count;
end
--[[
len
This function returns the length of the target string.
Usage:
{{#invoke:String|len|target_string|}}
OR
{{#invoke:String|len|s=target_string}}
Parameters
s: The string whose length to report
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the target string.
]]
function str.len( frame )
local new_args = str._getParameters( frame.args, {'s'} );
local s = new_args['s'] or '';
return mw.ustring.len( s )
end
--[[
sub
This function returns a substring of the target string at specified indices.
Usage:
{{#invoke:String|sub|target_string|start_index|end_index}}
OR
{{#invoke:String|sub|s=target_string|i=start_index|j=end_index}}
Parameters
s: The string to return a subset of
i: The fist index of the substring to return, defaults to 1.
j: The last index of the string to return, defaults to the last character.
The first character of the string is assigned an index of 1. If either i or j
is a negative value, it is interpreted the same as selecting a character by
counting from the end of the string. Hence, a value of -1 is the same as
selecting the last character of the string.
If the requested indices are out of range for the given string, an error is
reported.
]]
function str.sub( frame )
local new_args = str._getParameters( frame.args, { 's', 'i', 'j' } );
local s = new_args['s'] or '';
local i = tonumber( new_args['i'] ) or 1;
local j = tonumber( new_args['j'] ) or -1;
local len = mw.ustring.len( s );
-- Convert negatives for range checking
if i < 0 then
i = len + i + 1;
end
if j < 0 then
j = len + j + 1;
end
if i > len or j > len or i < 1 or j < 1 then
return str._error( 'Значение индекса подстроки выходит за допустимые границы' );
end
if j < i then
return str._error( 'Неверный порядок индексов подстроки' );
end
return mw.ustring.sub( s, i, j )
end
--[[
This function implements that features of {{str sub old}} and is kept in order
to maintain these older templates.
]]
function str.sublength( frame )
local i = tonumber( frame.args.i ) or 0
local len = tonumber( frame.args.len )
return mw.ustring.sub( frame.args.s, i + 1, len and ( i + len ) )
end
--[[
match
This function returns a substring from the source string that matches a
specified pattern.
Usage:
{{#invoke:String|match|source_string|pattern_string|start_index|match_number|plain_flag|nomatch_output}}
OR
{{#invoke:String|pos|s=source_string|pattern=pattern_string|start=start_index
|match=match_number|plain=plain_flag|nomatch=nomatch_output}}
Parameters
s: The string to search
pattern: The pattern or string to find within the string
start: The index within the source string to start the search. The first
character of the string has index 1. Defaults to 1.
match: In some cases it may be possible to make multiple matches on a single
string. This specifies which match to return, where the first match is
match= 1. If a negative number is specified then a match is returned
counting from the last match. Hence match = -1 is the same as requesting
the last match. Defaults to 1.
plain: A flag indicating that the pattern should be understood as plain
text. Defaults to false.
nomatch: If no match is found, output the "nomatch" value rather than an error.
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from each string. In some circumstances this is desirable, in
other cases one may want to preserve the whitespace.
If the match_number or start_index are out of range for the string being queried, then
this function generates an error. An error is also generated if no match is found.
If one adds the parameter ignore_errors=true, then the error will be suppressed and
an empty string will be returned on any failure.
For information on constructing Lua patterns, a form of [regular expression], see:
* http://www.lua.org/manual/5.1/manual.html#5.4.1
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Ustring_patterns
]]
function str.match( frame )
local new_args = str._getParameters( frame.args, {'s', 'pattern', 'start', 'match', 'plain', 'nomatch'} );
local s = new_args['s'] or '';
local start = tonumber( new_args['start'] ) or 1;
local plain_flag = str._getBoolean( new_args['plain'] or false );
local pattern = new_args['pattern'] or '';
local match_index = math.floor( tonumber(new_args['match']) or 1 );
local nomatch = new_args['nomatch'];
if s == '' then
return str._error( 'Пустая строка поиска' );
end
if pattern == '' then
return str._error( 'Пустой шаблон поиска' );
end
if math.abs(start) < 1 or math.abs(start) > mw.ustring.len( s ) then
return str._error( 'Индекс начала поиска выходит за допустимые границы' );
end
if match_index == 0 then
return str._error( 'Индекс совпадения выходит за допустимые границы' );
end
if plain_flag then
pattern = str._escapePattern( pattern );
end
local result
if match_index == 1 then
-- Find first match is simple case
result = mw.ustring.match( s, pattern, start )
else
if start > 1 then
s = mw.ustring.sub( s, start );
end
local iterator = mw.ustring.gmatch(s, pattern);
if match_index > 0 then
-- Forward search
for w in iterator do
match_index = match_index - 1;
if match_index == 0 then
result = w;
break;
end
end
else
-- Reverse search
local result_table = {};
local count = 1;
for w in iterator do
result_table[count] = w;
count = count + 1;
end
result = result_table[ count + match_index ];
end
end
if result == nil then
if nomatch == nil then
return str._error( 'Совпадение не найдено' );
else
return nomatch;
end
else
return result;
end
end
--[[
pos
This function returns a single character from the target string at position pos.
Usage:
{{#invoke:String|pos|target_string|index_value}}
OR
{{#invoke:String|pos|target=target_string|pos=index_value}}
Parameters
target: The string to search
pos: The index for the character to return
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the target string. In some circumstances this is desirable, in
other cases one may want to preserve the whitespace.
The first character has an index value of 1.
If one requests a negative value, this function will select a character by counting backwards
from the end of the string. In other words pos = -1 is the same as asking for the last character.
A requested value of zero, or a value greater than the length of the string returns an error.
]]
function str.pos( frame )
local new_args = str._getParameters( frame.args, {'target', 'pos'} );
local target_str = new_args['target'] or '';
local pos = tonumber( new_args['pos'] ) or 0;
if pos == 0 or math.abs(pos) > mw.ustring.len( target_str ) then
return str._error( 'Значение индекса строки выходит за допустимые границы' );
end
return mw.ustring.sub( target_str, pos, pos );
end
--[[
str_find
This function duplicates the behavior of {{str_find}}, including all of its quirks.
This is provided in order to support existing templates, but is NOT RECOMMENDED for
new code and templates. New code is recommended to use the "find" function instead.
Returns the first index in "source" that is a match to "target". Indexing is 1-based,
and the function returns -1 if the "target" string is not present in "source".
Important Note: If the "target" string is empty / missing, this function returns a
value of "1", which is generally unexpected behavior, and must be accounted for
separatetly.
]]
function str.str_find( frame )
local new_args = str._getParameters( frame.args, {'source', 'target'} );
local source_str = new_args['source'] or '';
local target_str = new_args['target'] or '';
if target_str == '' then
return 1;
end
local start = mw.ustring.find( source_str, target_str, 1, true )
if start == nil then
start = -1
end
return start
end
--[[
find
This function allows one to search for a target string or pattern within another
string.
Usage:
{{#invoke:String|find|source_str|target_string|start_index|plain_flag}}
OR
{{#invoke:String|find|source=source_str|target=target_str|start=start_index|plain=plain_flag}}
Parameters
source: The string to search
target: The string or pattern to find within source
start: The index within the source string to start the search, defaults to 1
plain: Boolean flag indicating that target should be understood as plain
text and not as a Lua style regular expression, defaults to true
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the parameter. In some circumstances this is desirable, in
other cases one may want to preserve the whitespace.
This function returns the first index >= "start" where "target" can be found
within "source". Indices are 1-based. If "target" is not found, then this
function returns 0. If either "source" or "target" are missing / empty, this
function also returns 0.
This function should be safe for UTF-8 strings.
]]
function str.find( frame )
local new_args = str._getParameters( frame.args, {'source', 'target', 'start', 'plain' } );
local source_str = new_args['source'] or '';
local pattern = new_args['target'] or '';
local start_pos = tonumber(new_args['start']) or 1;
local plain = new_args['plain'] or true;
if source_str == '' or pattern == '' then
return 0;
end
plain = str._getBoolean( plain );
local start = mw.ustring.find( source_str, pattern, start_pos, plain )
if start == nil then
start = 0
end
return start
end
--[[
replace
This function allows one to replace a target string or pattern within another
string.
Usage:
{{#invoke:String|replace|source_str|pattern_string|replace_string|replacement_count|plain_flag}}
OR
{{#invoke:String|replace|source=source_string|pattern=pattern_string|replace=replace_string|
count=replacement_count|plain=plain_flag}}
Parameters
source: The string to search
pattern: The string or pattern to find within source
replace: The replacement text
count: The number of occurences to replace, defaults to all.
plain: Boolean flag indicating that pattern should be understood as plain
text and not as a Lua style regular expression, defaults to true
]]
function str.replace( frame )
local new_args = str._getParameters( frame.args, {'source', 'pattern', 'replace', 'count', 'plain' } );
local source_str = new_args['source'] or '';
local pattern = new_args['pattern'] or '';
local replace = new_args['replace'] or '';
local count = tonumber( new_args['count'] );
local plain = new_args['plain'] or true;
if source_str == '' or pattern == '' then
return source_str;
end
plain = str._getBoolean( plain );
if plain then
pattern = str._escapePattern( pattern );
replace = mw.ustring.gsub( replace, "%%", "%%%%" ); --Only need to escape replacement sequences.
end
local result;
if count ~= nil then
result = mw.ustring.gsub( source_str, pattern, replace, count );
else
result = mw.ustring.gsub( source_str, pattern, replace );
end
return result;
end
--[[
This function adds support for escaping parts of the patterns when using [plain=false].
]]
function str.escape( frame )
local new_args = str._getParameters( frame.args, {'pattern' } );
local pattern = new_args['pattern'] or '';
local result = '';
result = str._escapePattern( pattern );
return result;
end
--[[
Internal compare string function
]]
function str._strcmp(a , b)
local s1c = mw.ustring.gcodepoint( a );
local s2c = mw.ustring.gcodepoint( b );
while true do
local c1 = s1c();
local c2 = s2c();
if c1 == nil then
if c2 == nil then
return 0
else
return -1
end
else
if c2 ~= nil then
if c1 ~= c2 then
return c1 < c2 and -1 or 1
end
else
return 1
end
end
end
return 0
end
--[[
compare
This function compare two UTF-8 strings
Usage:
{{#invoke:String|compare|str1|str2}}
Returns:
0 - if strings are equal
1 - if st1 > str2
-1 - if str1 < str2
]]
function str.compare(frame)
local str1 = frame.args[1] or '';
local str2 = frame.args[2] or '';
return str._strcmp(str1 , str2)
end
--[[
simple function to pipe string.rep to templates.
]]
function str.rep( frame )
local repetitions = tonumber( frame.args[2] )
if not repetitions then
return str._error( 'функция rep ожидает число во втором параметре, а получено "' .. ( frame.args[2] or '' ) .. '"' )
end
return string.rep( frame.args[1] or '', repetitions )
end
--[[
Helper function that populates the argument list given that user may need to use a mix of
named and unnamed parameters. This is relevant because named parameters are not
identical to unnamed parameters due to string trimming, and when dealing with strings
we sometimes want to either preserve or remove that whitespace depending on the application.
]]
function str._getParameters( frame_args, arg_list )
local new_args = {};
local index = 1;
local value;
for i,arg in ipairs( arg_list ) do
value = frame_args[arg]
if value == nil then
value = frame_args[index];
index = index + 1;
end
new_args[arg] = value;
end
return new_args;
end
--[[
Helper function to handle error messages.
]]
function str._error( error_str )
local frame = mw.getCurrentFrame();
local error_category = frame.args.error_category or 'Страницы с ошибками модуля String';
local ignore_errors = frame.args.ignore_errors or false;
local no_category = frame.args.no_category or false;
if str._getBoolean(ignore_errors) then
return '';
end
local error_str = '<strong class="error">Ошибка модуля String: ' .. error_str .. '</strong>';
if error_category ~= '' and not str._getBoolean( no_category ) then
error_str = '[[Категория:' .. error_category .. ']]' .. error_str;
end
return error_str;
end
--[[
Helper Function to interpret boolean strings
]]
function str._getBoolean( boolean_str )
local boolean_value;
if type( boolean_str ) == 'string' then
boolean_str = boolean_str:lower();
if boolean_str == 'false' or boolean_str == 'no' or boolean_str == '0'
or boolean_str == '' then
boolean_value = false;
else
boolean_value = true;
end
elseif type( boolean_str ) == 'boolean' then
boolean_value = boolean_str;
else
error( 'Логическое значение не найдено' );
end
return boolean_value
end
--[[
Helper function that escapes all pattern characters so that they will be treated
as plain text.
]]
function str._escapePattern( pattern_str )
return mw.ustring.gsub( pattern_str, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" );
end
return str
b4a4e099d7fab23576bae7af327a44c87d13f9cb
Модуль:Sources
828
140
323
322
2024-08-10T15:21:02Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
---@alias args table
---@alias frame { args: args, extensionTag: function, newChild: ( fun( args: args ): frame ) }
---@alias source { publication: source, [string]: any }
---@alias value: string | { id: string }
---@alias snak { datatype: string, snaktype: string, datavalue: { type: string, value: value } }
---@alias snaks table<string, table<number, snak>>
---@alias statement { mainsnak: snak, rank: string, qualifiers: snaks }
---@alias statements table<string, table<number, statement>>
---@alias map { name: string, ids: string[] }[]>
---@type table
local p = {}
---@type table<string, string>
local NORMATIVE_DOCUMENTS = {
Q20754888 = 'Закон Российской Федерации',
Q20754884 = 'Закон РСФСР',
Q20873831 = 'Распоряжение Президента Российской Федерации',
Q20873834 = 'Указ исполняющего обязанности Президента Российской Федерации',
Q2061228 = 'Указ Президента Российской Федерации',
}
---@type table<string, string>
local LANG_CACHE = {
Q150 = 'fr',
Q188 = 'de',
Q1321 = 'es',
Q1860 = 'en',
Q652 = 'it',
Q7737 = 'ru',
Q8798 = 'uk',
}
---@type map
local PROPERTY_MAP = {
{ name = 'sourceId', ids = { 'P248', 'P805' } },
{ name = 'lang', ids = { 'P407', 'P364' } },
{ name = 'author', ids = { 'P50', 'P2093' } },
{ name = 'part', ids = { 'P958', 'P1810' } },
{ name = 'title', ids = { 'P1476' } },
{ name = 'subtitle', ids = { 'P1680' } },
{ name = 'url', ids = { 'P953', 'P1065', 'P854', 'P973', 'P2699', 'P888' } },
{ name = 'editor', ids = { 'P98' } },
{ name = 'translator', ids = { 'P655' } },
{ name = 'publication-id', ids = { 'P1433' } },
{ name = 'edition', ids = { 'P393' } },
{ name = 'publisher', ids = { 'P123' } },
{ name = 'place', ids = { 'P291' } },
{ name = 'volume', ids = { 'P478' } },
{ name = 'issue', ids = { 'P433' } },
{ name = 'dateOfCreation', ids = { 'P571' } },
{ name = 'dateOfPublication', ids = { 'P577' } },
{ name = 'pages', ids = { 'P304' } },
{ name = 'numberOfPages', ids = { 'P1104' } },
{ name = 'tirage', ids = { 'P1092' } },
{ name = 'isbn', ids = { 'P212', 'P957' } },
{ name = 'issn', ids = { 'P236' } },
-- { name = 'accessdate', ids = { 'P813' } }, -- disable, creates duplicate references
{ name = 'docNumber', ids = { 'P1545' } },
{ name = 'type', ids = { 'P31' } },
{ name = 'arxiv', ids = { 'P818' } },
{ name = 'doi', ids = { 'P356' } },
{ name = 'pmid', ids = { 'P698' } },
}
-- table.insert( PROPERTY_MAP.url, 'P856' ) -- only as qualifier
---@type map
local PUBLICATION_PROPERTY_MAP = mw.clone( PROPERTY_MAP )
---@type string[]
local monthGen = { 'января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря' }
---@type string
local i18nDefaultLanguage = mw.language.getContentLanguage():getCode()
p.i18nDefaultLanguage = i18nDefaultLanguage
---@type string
local i18nEtAlDefault = ' et al.'
---@type table<string, string>
local i18nEtAl = {
ru = ' и др.',
uk = ' та ін.',
}
---@type table<string, string>
local i18nEditors = {
fr = '',
de = 'Hrsg.: ',
es = '',
en = '',
it = '',
ru = 'под ред. ',
uk = 'за ред. ',
}
---@type table<string, string>
local i18nTranslators = {
fr = '',
de = '',
es = '',
en = '',
it = '',
ru = 'пер. ',
uk = 'пер. ',
}
---@type table<string, string>
local i18nVolume = {
de = 'Vol.',
fr = 'Vol.',
es = 'Vol.',
en = 'Vol.',
it = 'Vol.',
ru = 'Т.',
uk = 'Т.',
}
---@type table<string, string>
local i18nIssue = {
en = 'Iss.',
ru = 'вып.',
uk = 'вип.',
}
---@type table<string, string>
local i18nPages = {
fr = 'P.',
de = 'S.',
es = 'P.',
en = 'P.',
it = 'P.',
ru = 'С.',
uk = 'С.',
}
---@type table<string, string>
local i18nNumberOfPages = {
en = 'p.',
ru = 'с.',
}
---@type table<string, string>
local i18nTirage = {
en = 'ed. size: %d',
ru = '%d экз.',
}
---@param args args
---@return source
local function getFilledArgs( args )
---@type source
local data = {}
for key, value in pairs( args ) do
if mw.text.trim( value ) ~= '' then
if key == 1 then
key = 'sourceId'
end
data[ key ] = mw.text.trim( value )
end
end
return data
end
---Returns formatted pair {Family name(s), First name(s)}
---@param fullName string
---@return table<number, string>
local function tokenizeName( fullName )
local space = '%s+' -- matches single or more spacing character
local name = "(%a[%a%-']*)%.?" -- matches single name, have to start with letter, can contain apostrophe and hyphen, may end with dot
local surname = "(%a[%a%-']*)" -- same as name, but can't end with dot
local surnamePrefixes = { 'ван', 'van', 'де', 'de' }
local nm, nm2, srn, srn2, pref
fullName = ' ' .. fullName .. ' '
fullName = mw.ustring.gsub( fullName, ' оглы ', ' ' )
fullName = mw.text.trim( fullName )
-- Surname, Name
local pattern = '^' .. surname .. ',' .. space .. name .. '$'
srn, nm = mw.ustring.match( fullName, pattern )
if srn then
return {
srn,
mw.ustring.sub( nm, 1, 1 ) .. '.'
}
end
-- Surname, Name prefix
for _, surnamePrefix in pairs( surnamePrefixes ) do
pattern = '^' .. surname .. ',' .. space .. name .. space .. '(' .. surnamePrefix .. ')' .. '$'
srn, nm, pref = mw.ustring.match( fullName, pattern )
if srn then
return {
mw.ustring.sub( pref ) .. ' ' .. srn,
mw.ustring.sub( nm, 1, 1 ) .. '.' }
end
end
-- Surname, Name Name
pattern = '^' .. surname .. ',' .. space .. name .. space .. name .. '$'
srn, nm, nm2 = mw.ustring.match( fullName, pattern )
if srn then
return {
srn,
mw.ustring.sub( nm, 1, 1 ) .. '. ' .. mw.ustring.sub( nm2, 1, 1 ) .. '.'
}
end
-- Surname Surname, Name
pattern = '^' .. surname .. space .. surname .. ',' .. space .. name .. '$'
srn, srn2, nm = mw.ustring.match( fullName, pattern )
if srn then
return {
srn .. ' ' .. srn2,
mw.ustring.sub( nm, 1, 1 ) .. '.'
}
end
-- Name Name Surname
pattern = '^' .. name .. space .. name .. space .. surname .. '$'
nm, nm2, srn = mw.ustring.match( fullName, pattern )
if srn then
return {
srn,
mw.ustring.sub( nm, 1, 1 ) .. '. ' .. mw.ustring.sub( nm2, 1, 1 ) .. '.'
}
end
-- Name Name prefix Surname
for _, surnamePrefix in pairs( surnamePrefixes ) do
pattern = '^' .. name .. space .. name .. space .. '(' .. surnamePrefix .. ')' .. space .. surname .. '$'
nm, nm2, pref, srn = mw.ustring.match( fullName, pattern )
if srn then
return {
mw.ustring.sub( pref ) .. ' ' .. srn,
mw.ustring.sub( nm, 1, 1 ) .. '. ' .. mw.ustring.sub( nm2, 1, 1 ) .. '.'
}
end
end
-- Surname, Name Name prefix
for _, surnamePrefix in pairs( surnamePrefixes ) do
pattern = '^' .. surname .. ',' .. space .. name .. space .. name .. space .. '(' .. surnamePrefix .. ')' .. '$'
srn, nm, nm2, pref = mw.ustring.match( fullName, pattern )
if srn then
return {
mw.ustring.sub( pref ) .. ' ' .. srn,
mw.ustring.sub( nm, 1, 1 ) .. '. ' .. mw.ustring.sub( nm2, 1, 1 ) .. '.'
}
end
end
-- Name{1,4} Surname
for k = 1, 4 do
pattern = '^' .. string.rep( name .. space, k ) .. surname .. '$'
---@type string[]
local matched = { mw.ustring.match( fullName, pattern ) }
if #matched ~= 0 then
for j = 1, k do
matched[ j ] = mw.ustring.sub( matched[ j ], 1, 1 )
end
return {
matched[ k + 1 ],
table.concat( matched, '. ', 1, k ) .. '.'
}
end
end
-- Surname Name{1,4}
for k = 1, 4 do
pattern = '^' .. surname .. string.rep( space .. name, k ) .. '$'
---@type string[]
local matched = { mw.ustring.match( fullName, pattern ) }
if #matched ~= 0 then
for j = 2, k + 1 do
matched[ j ] = mw.ustring.sub( matched[ j ], 1, 1 )
end
return {
matched[ 1 ],
table.concat( matched, '. ', 2, k + 1 ) .. '.'
}
end
end
return { fullName }
end
---@param fullName string | nil
---@return string | nil
local function personNameToAuthorName( fullName )
if not fullName then
return nil
end
local tokenized = tokenizeName( fullName )
if #tokenized == 1 then
return tokenized[ 1 ]
end
return tokenized[ 1 ] .. ' ' .. tokenized[ 2 ]
end
---@param fullName string | nil
---@return string | nil
local function personNameToResponsibleName( fullName )
if not fullName then
return nil
end
local tokenized = tokenizeName( fullName )
if #tokenized == 1 then
return tokenized[ 1 ]
end
return tokenized[ 2 ] .. ' ' .. tokenized[ 1 ]
end
---@alias options { separator: string, conjunction: string, format: ( fun( data: string ): string ), nolinks: boolean, preferids: boolean, short: boolean }
---@type options
local options_commas = {
separator = ', ',
conjunction = ', ',
format = function( data ) return data end,
nolinks = false,
preferids = false,
short = false,
}
---@type options
local options_commas_short = mw.clone( options_commas )
options_commas_short.short = true
---@type options
local options_commas_it_short = mw.clone( options_commas_short )
options_commas_it_short.format = function( data ) return "''" .. data .. "''" end
---@type options
local options_commas_nolinks = mw.clone( options_commas )
options_commas_nolinks.nolinks = true
---@type options
local options_citetypes = {
separator = ' ',
conjunction = ' ',
format = function( data ) return 'citetype_' .. data end,
nolinks = true ,
preferids = true,
short = false,
}
---@type options
local options_commas_authors = mw.clone( options_commas )
options_commas_authors.format = personNameToAuthorName
---@type options
local options_commas_responsible = mw.clone( options_commas )
options_commas_responsible.format = personNameToResponsibleName
---@type options
local options_ids = {
separator = '; ',
conjunction = '; ',
format = function( id ) return id end,
nolinks = true,
preferids = false,
short = false,
}
---@type options
local options_arxiv = mw.clone( options_ids )
options_arxiv.format = function( id ) return '[https://arxiv.org/abs/' .. id .. ' arXiv:' .. id .. ']' end
---@type options
local options_doi = mw.clone( options_ids )
options_doi.format = function( doi ) return '[https://dx.doi.org/' .. doi .. ' doi:' .. doi .. ']' end
---@type options
local options_issn = mw.clone( options_ids )
options_issn.format = function( issn ) return '[https://www.worldcat.org/issn/' .. issn .. ' ' .. issn .. ']' end
---@type options
local options_pmid = mw.clone( options_ids )
options_pmid.format = function( pmid ) return '[https://www.ncbi.nlm.nih.gov/pubmed/?term=' .. pmid .. ' PMID:' .. pmid .. ']' end
---@param str string | nil
---@return boolean
local function isEmpty( str )
return not str or #str == 0
end
---@param allQualifiers snaks
---@param qualifierPropertyId string
---@return string | nil
local function getSingleStringQualifierValue( allQualifiers, qualifierPropertyId )
if not allQualifiers or not allQualifiers[ qualifierPropertyId ] then
return nil
end
---@type table<number, snak>
local propertyQualifiers = allQualifiers[ qualifierPropertyId ]
for _, qualifier in pairs( propertyQualifiers ) do
if ( qualifier
and qualifier.datatype == 'string'
and qualifier.datavalue
and qualifier.datavalue.type == 'string'
and qualifier.datavalue.value ~= ''
) then
return qualifier.datavalue.value
end
end
return nil
end
---@param data table
---@param resultProperty string
---@return void
local function appendImpl_toTable( data, resultProperty )
if not data[ resultProperty ] then
data[ resultProperty ] = {}
elseif ( type( data[ resultProperty ] ) == 'string' or ( type( data[ resultProperty ] ) == 'table' and type( data[ resultProperty ].id ) == 'string' ) ) then
data[ resultProperty ] = { data[ resultProperty ] }
end
end
---@param datavalue table
---@param qualifiers snaks
---@param data table
---@param propertyName string
---@param options table
local function appendImpl( datavalue, qualifiers, data, propertyName, options )
data[ propertyName ] = data[ propertyName ] or {}
if propertyName == 'issn' then
table.insert( data[ propertyName ], datavalue.value )
elseif propertyName == 'url' or datavalue.type == 'url' then
local value = datavalue.value
if options.format then
value = options.format( value )
end
appendImpl_toTable( data, propertyName )
table.insert( data[ propertyName ], value )
elseif datavalue.type == 'string' then
local value = getSingleStringQualifierValue( qualifiers, 'P1932' )
if not value then
value = getSingleStringQualifierValue( qualifiers, 'P1810' )
end
if not value then
value = datavalue.value
if options.format then
value = options.format( value )
end
end
appendImpl_toTable(data, propertyName)
local pos = getSingleStringQualifierValue( qualifiers, 'P1545' )
if pos then
table.insert( data[ propertyName ], tonumber(pos), value )
else
table.insert( data[ propertyName ], value )
end
elseif datavalue.type == 'monolingualtext' then
local value = datavalue.value.text
if options.format then
value = options.format( value )
end
appendImpl_toTable( data, propertyName )
table.insert( data[ propertyName ], value )
elseif datavalue.type == 'quantity' then
local value = datavalue.value.amount
if ( mw.ustring.sub( value , 1, 1 ) == '+' ) then
value = mw.ustring.sub( value , 2 )
end
if options.format then
value = options.format( value )
end
appendImpl_toTable( data, propertyName )
table.insert( data[ propertyName ], value )
elseif datavalue.type == 'wikibase-entityid' then
local pos = getSingleStringQualifierValue( qualifiers, 'P1545' )
local value = datavalue.value
appendImpl_toTable(data, propertyName)
local label = getSingleStringQualifierValue( qualifiers, 'P1932' )
if not label then
label = getSingleStringQualifierValue( qualifiers, 'P1810' )
end
local toInsert = {
id = value.id,
label = label
}
if pos and tonumber( pos ) then
table.insert( data[ propertyName ], tonumber( pos ), toInsert )
else
table.insert( data[ propertyName ], toInsert )
end
elseif datavalue.type == 'time' then
local value = datavalue.value
if options.format then
value = options.format( value )
end
appendImpl_toTable( data, propertyName )
table.insert( data[ propertyName ], tostring( value.time ) )
end
end
---@param entityId string
---@param propertyId string
---@return table<number, statement>
local function getAllStatements( entityId, propertyId )
---@type boolean, table<number, statement>
local wdStatus, statements = pcall( mw.wikibase.getAllStatements, entityId, propertyId )
if wdStatus and statements then
return statements
end
return {}
end
---@param entityId string
---@param propertyId string
---@return table<number, statement>
local function getBestStatements( entityId, propertyId )
---@type boolean, table<number, statement>
local wdStatus, statements = pcall( mw.wikibase.getBestStatements, entityId, propertyId )
if wdStatus and statements then
return statements
end
return {}
end
---@param entityId string
---@param projectToCheck string?
---@return string | nil
local function getSitelink( entityId, projectToCheck )
---@type boolean, string
local wbStatus, sitelink
if projectToCheck then
wbStatus, sitelink = pcall( mw.wikibase.getSitelink, entityId, projectToCheck )
else
wbStatus, sitelink = pcall( mw.wikibase.getSitelink, entityId )
end
if not wbStatus then
return nil
end
return sitelink
end
---@param args any[]
---@return any | nil
local function coalesce( args )
for _, arg in pairs( args ) do
if not isEmpty( arg ) then return arg end
end
return nil
end
---@param value any
---@return string | nil
local function getSingle( value )
if type( value ) == 'string' then
return tostring( value )
elseif type( value ) == 'table' then
if value.id then
return tostring( value.id )
end
for _, tableValue in pairs( value ) do
return getSingle( tableValue )
end
end
return nil
end
---@param langEntityId string
---@return string | nil
local function getLangCode( langEntityId )
if not langEntityId then
return nil
end
langEntityId = getSingle( langEntityId )
if not string.match( langEntityId, '^Q%d+$' ) then
return langEntityId
end
local cached = LANG_CACHE[ langEntityId ]
if cached then
if cached == '' then
return nil
end
return cached
end
local claims = getBestStatements( langEntityId, 'P424' )
for _, claim in pairs( claims ) do
if claim
and claim.mainsnak
and claim.mainsnak.datavalue
and claim.mainsnak.datavalue.value
then
LANG_CACHE[ langEntityId ] = claim.mainsnak.datavalue.value
return claim.mainsnak.datavalue.value
end
end
LANG_CACHE[ langEntityId ] = ''
return nil
end
---@param entityId string
---@param propertyId string
---@param data source
---@param propertyName string
---@param options table?
---@return void
local function appendEntitySnaks( entityId, propertyId, data, propertyName, options )
options = options or {}
-- do not populate twice
if data[ propertyName ] and ( propertyName ~= 'author' or data[ propertyId ] ) then
return
end
local statements = getBestStatements( entityId, propertyId )
if propertyName == 'author' then
data[ propertyId ] = true
end
local lang = getLangCode( data.lang ) or i18nDefaultLanguage
if propertyId == 'P1680' then -- if there is a default language
for _, statement in pairs( statements ) do
if statement and
statement.mainsnak and
statement.mainsnak.datavalue and
statement.mainsnak.datavalue.value and
statement.mainsnak.datavalue.value.language == lang
then
--found default language string
appendImpl( statement.mainsnak.datavalue, statement.qualifiers, data, propertyName, options )
return
end
end
end
for _, statement in pairs( statements ) do
if statement and statement.mainsnak and statement.mainsnak.datavalue then
appendImpl( statement.mainsnak.datavalue, statement.qualifiers or {}, data, propertyName, options )
if propertyName == 'publication-id' and statement.qualifiers then
data[ 'publication-qualifiers' ] = statement.qualifiers
end
end
end
end
---@param claims table<number, statement>
---@param qualifierPropertyId string
---@param result table
---@param resultPropertyId string
---@param options table
---@return void
local function appendQualifiers( claims, qualifierPropertyId, result, resultPropertyId, options )
-- do not populate twice
if not claims or result[ resultPropertyId ] then
return
end
for _, claim in pairs( claims ) do
if claim.qualifiers and claim.qualifiers[ qualifierPropertyId ] then
---@type table<number, snak>
local propertyQualifiers = claim.qualifiers[ qualifierPropertyId ]
for _, qualifier in pairs( propertyQualifiers ) do
if qualifier and qualifier.datavalue then
appendImpl( qualifier.datavalue, nil, result, resultPropertyId, options )
end
end
end
end
end
---@param entityId string
---@param propertyId string
---@param value any
---@return table<number, statement>
local function findClaimsByValue( entityId, propertyId, value )
local result = {}
local claims = getAllStatements( entityId, propertyId )
for _, claim in pairs( claims ) do
if ( claim.mainsnak and claim.mainsnak.datavalue ) then
local datavalue = claim.mainsnak.datavalue
if ( datavalue.type == "string" and datavalue.value == value ) or
( datavalue.type == "wikibase-entityid" and
datavalue.value[ "entity-type" ] == "item" and
tostring( datavalue.value.id ) == value )
then
table.insert( result, claim )
end
end
end
return result
end
---@param entityId string
---@param typeEntityId string
---@return boolean
local function isInstanceOf( entityId, typeEntityId )
return findClaimsByValue( entityId, 'P31', typeEntityId )[ 1 ] ~= nil
end
---@param entityId string
---@param typeEntityIds string[]
---@return string
---@todo Rewrite
local function getFirstType( entityId, typeEntityIds )
for _, typeEntityId in pairs( typeEntityIds ) do
if isInstanceOf( entityId, typeEntityId ) then
return typeEntityId
end
end
return nil
end
---@param snaks snaks
---@param data source
---@param map map
---@return void
local function populateDataFromSnaks( snaks, data, map )
for _, row in ipairs( map ) do
local parameterName, propertyIds = row.name, row.ids
for _, propertyId in pairs( propertyIds ) do
if not data[ parameterName ] and snaks[ propertyId ] then
local options = {}
if propertyId == 'P888' then
options = { format = function( id ) return 'http://www.jstor.org/stable/' .. id end }
end
for _, snak in pairs( snaks[ propertyId ] ) do
if snak and snak.datavalue then
appendImpl( snak.datavalue, {}, data, parameterName, options )
end
end
end
end
end
end
---@param entityId string | nil
---@param data source
---@param map map
---@return void
local function populateDataFromEntity( entityId, data, map )
if not data.title then
if not isEmpty( entityId ) then
local optionsAsLinks = { format = function( text ) return { id = entityId, label = text } end }
appendEntitySnaks( entityId, 'P1476', data, 'title', optionsAsLinks )
else
appendEntitySnaks( entityId, 'P1476', data, 'title', {} )
end
appendEntitySnaks( entityId, 'P1680', data, 'subtitle', {} )
end
local bookSeriesStatements = getBestStatements( entityId, 'P361' )
for _, statement in pairs( bookSeriesStatements ) do
if statement and
statement.mainsnak and
statement.mainsnak.datavalue and
statement.mainsnak.datavalue.value and
statement.mainsnak.datavalue.value.id
then
local possibleBookSeriesEntityId = statement.mainsnak.datavalue.value.id
if isInstanceOf( possibleBookSeriesEntityId, 'Q277759' ) then
appendImpl_toTable( data, 'bookSeries' )
table.insert( data.bookSeries, { id = possibleBookSeriesEntityId } )
appendQualifiers( { statement }, 'P478', data, 'bookSeriesVolume', {} )
appendQualifiers( { statement }, 'P433', data, 'bookSeriesIssue', {} )
end
end
end
for _, row in ipairs( map ) do
local parameterName, propertyIds = row.name, row.ids
for _, propertyId in pairs( propertyIds ) do
local options = {}
if propertyId == 'P888' then
options = { format = function( id ) return 'http://www.jstor.org/stable/' .. id end }
end
appendEntitySnaks( entityId, propertyId, data, parameterName, options )
end
end
end
---@param data source
---@return void
local function expandPublication( data )
if not data[ 'publication-id' ] then
return
end
local publicationId = getSingle( data[ 'publication-id' ] )
data.publication = {}
for key, value in pairs( data ) do
if not string.match( key, '^publication-' ) then
data.publication[ key ] = value
end
end
data.publication.sourceId = publicationId
data.publication.title = data[ 'publication-title' ]
data.publication.subtitle = data[ 'publication-subtitle' ]
if data[ 'publication-qualifiers' ] then
populateDataFromSnaks( data[ 'publication-qualifiers' ], data.publication, PUBLICATION_PROPERTY_MAP )
end
populateDataFromEntity( publicationId, data.publication, PUBLICATION_PROPERTY_MAP )
if type( data.publication.title ) == 'table' and data.publication.title[ 1 ] then
data.publication.title = data.publication.title[ 1 ]
end
if type( data.publication.subtitle ) == 'table' and data.publication.subtitle[ 1 ] then
data.publication.subtitle = data.publication.subtitle[ 1 ]
end
for key, value in pairs( data.publication ) do
if key ~= 'sourceId' and key ~= 'title' and key ~= 'subtitle' and key ~= 'url' and not data[ key ] then
data[ key ] = value
end
end
end
---@param data source
---@return void
local function expandBookSeries( data )
local bookSeries = data.bookSeries
if not bookSeries then
return
end
-- use only first one
if type( bookSeries ) == 'table' and bookSeries[ 1 ] and bookSeries[ 1 ].id then
data.bookSeries = bookSeries[ 1 ]
bookSeries = data.bookSeries
end
if not bookSeries or not bookSeries.id then
return
end
appendEntitySnaks( bookSeries.id, 'P123', data, 'publisher', {} )
appendEntitySnaks( bookSeries.id, 'P291', data, 'place', {} )
appendEntitySnaks( bookSeries.id, 'P236', data, 'issn', {} )
end
---@param entityId string
---@return string | nil
local function getNormativeTitle( entityId )
local possibleTypeIds = {}
for typeId, _ in pairs( NORMATIVE_DOCUMENTS ) do
table.insert( possibleTypeIds, typeId )
end
local foundTypeId = getFirstType( entityId, possibleTypeIds )
if foundTypeId then
return NORMATIVE_DOCUMENTS[ foundTypeId ]
end
return nil
end
---@param urls table<number, string> | string
---@param text string
---@return string
local function wrapInUrl( urls, text )
local url = getSingle( urls )
if string.sub( url, 1, 1 ) == ':' then
return '[[' .. url .. '|' .. text .. ']]'
else
return '[' .. url .. ' ' .. text .. ']'
end
end
---@param entityId string
---@param lang string
---@return string
local function getElementLink( entityId, lang )
local sitelink = getSitelink( entityId, nil )
if sitelink then
return ':' .. sitelink
end
if lang ~= 'mul' then
-- link to entity in source language
sitelink = getSitelink( entityId, lang .. 'wiki' )
if sitelink then
return ':' .. lang .. ':' .. sitelink
end
end
return ':d:' .. entityId
end
---@param entityId string
---@param lang string
---@return string
local function getLabel( entityId, lang )
local wbStatus, label = pcall( mw.wikibase.getLabelByLang, entityId, lang )
if not wbStatus then
return ''
end
if label and label ~= '' then
return label
end
wbStatus, label = pcall( mw.wikibase.getLabel, entityId )
if not wbStatus then
return ''
end
return label or ''
end
---@param lang string
---@param entityId string
---@param customTitle string
---@param options table
local function renderLink( lang, entityId, customTitle, options )
if not entityId then
error( 'entityId is not specified' )
end
if type( entityId ) ~= 'string' then
error( 'entityId is not string, but ' .. type( entityId ) )
end
if type( customTitle or '' ) ~= 'string' then
error( 'customTitle is not string, but ' .. type( customTitle ) )
end
local title = customTitle
-- ISO 4
if isEmpty( title ) then
local propertyStatements = getBestStatements( entityId, 'P1160' )
for _, claim in pairs( propertyStatements ) do
if ( claim
and claim.mainsnak
and claim.mainsnak.datavalue
and claim.mainsnak.datavalue.value
and claim.mainsnak.datavalue.value.language == lang
) then
title = claim.mainsnak.datavalue.value.text
-- mw.log( 'Got title of ' .. entityId .. ' from ISO 4 claim: «' .. title .. '»' )
break
end
end
end
-- official name P1448
-- short name P1813
if isEmpty( title ) and options.short then
local propertyStatements = getBestStatements( entityId, 'P1813' )
for _, claim in pairs( propertyStatements ) do
if ( claim
and claim.mainsnak
and claim.mainsnak.datavalue
and claim.mainsnak.datavalue.value
and claim.mainsnak.datavalue.value.language == lang
) then
title = claim.mainsnak.datavalue.value.text
-- mw.log( 'Got title of ' .. entityId .. ' from short name claim: «' .. title .. '» (' .. lang .. ')' )
break
end
end
end
-- person name P1559
-- labels
if isEmpty( title ) then
title = getLabel( entityId, lang )
-- mw.log( 'Got title of ' .. entityId .. ' from label: «' .. title .. '» (' .. lang .. ')' )
end
local actualText = title or '\'\'(untranslated)\'\''
local link = getElementLink( entityId, lang )
return wrapInUrl( link, actualText )
end
---@param lang string
---@param value value
---@param options options
---@return string
local function asString( lang, value, options )
if type( value ) == 'string' then
return options.format( value )
end
if type( value ) ~= 'table' then
return options.format( '(unknown type)' )
end
if value.id then
-- this is link
if type( value.label or '' ) ~= 'string' then
mw.logObject( value, 'error value' )
error( 'label of table value is not string but ' .. type( value.label ) )
end
local title
if options.preferids then
title = value.id
elseif options.nolinks then
title = value.label or getLabel( value.id, lang )
else
title = renderLink( lang, value.id, value.label, options )
end
if title == '' then
title = "''(untranslated title)''"
end
return options.format( title )
end
local resultList = {}
for _, tableValue in pairs( value ) do
table.insert( resultList, asString( lang, tableValue, options ) )
end
return mw.text.listToText( resultList, options.separator, options.conjunction )
end
---@param entityId string
---@param data source
---@return source
local function populateSourceDataImpl( entityId, data, map )
local wsLink = getSitelink( entityId, 'ruwikisource' )
if wsLink and not mw.ustring.gmatch( wsLink, 'Категория:' ) then
data.url = ":ru:s:" .. wsLink
end
populateDataFromEntity( entityId, data, map )
local normativeTitle = getNormativeTitle( entityId )
if normativeTitle then
local y, m, d = mw.ustring.match( getSingle( data.dateOfCreation ) , "(%-?%d+)%-(%d+)%-(%d+)T" )
y, m, d = tonumber( y ),tonumber( m ), tonumber( d )
local title = asString( 'ru', data.title, options_commas_nolinks )
local docNumber = getSingle( data.docNumber )
data.title = {
normativeTitle ..
" от " .. tostring( d ) .. " " .. monthGen[ m ] .. " " .. tostring( y ) .. " г." ..
( docNumber and ( " № " .. docNumber ) or '' ) ..
' «' .. title.. '»'
}
end
if not data.title then
local lang = getLangCode( data.lang ) or i18nDefaultLanguage
local label = getLabel( entityId, lang )
if label ~= '' then
data.title = { label }
end
end
return data
end
---@param entityId string
---@param propertyId string
---@param data source
---@return void
local function expandSpecialsQualifiers( entityId, propertyId, data )
local statements = getBestStatements( entityId, propertyId )
for _, statement in pairs( statements ) do
populateDataFromSnaks( statement.qualifiers or {}, data, PROPERTY_MAP )
end
end
---Expand special types of references when additional data could be found in OTHER entity properties
---@param data source
---@return void
local function expandSpecials( data )
if not data.entityId then
return
end
if data.sourceId == 'Q36578' then
-- Gemeinsame Normdatei -- specified by P227
appendEntitySnaks( data.entityId, 'P227', data, 'part', { format = function(gnd ) return 'Record #' .. gnd; end } )
appendEntitySnaks( data.entityId, 'P227', data, 'url', { format = function(gnd ) return 'http://d-nb.info/gnd/' .. gnd .. '/'; end } )
data.year = '2012—2016'
expandSpecialsQualifiers( data.entityId, 'P227', data )
elseif data.sourceId == 'Q15222191' then
-- BNF -- specified by P268
appendEntitySnaks( data.entityId, 'P268', data, 'part', { format = function(id ) return 'Record #' .. id; end } )
appendEntitySnaks( data.entityId, 'P268', data, 'url', { format = function(id ) return 'http://catalogue.bnf.fr/ark:/12148/cb' .. id; end } )
expandSpecialsQualifiers( data.entityId, 'P268', data )
elseif data.sourceId == 'Q54919' then
-- VIAF -- specified by P214
appendEntitySnaks( data.entityId, 'P214', data, 'part', { format = function(id ) return 'Record #' .. id; end } )
appendEntitySnaks( data.entityId, 'P214', data, 'url', { format = function(id ) return 'https://viaf.org/viaf/' .. id; end } )
expandSpecialsQualifiers( data.entityId, 'P214', data )
else
-- generic property search
for _, sourceClaim in pairs( getBestStatements( data.sourceId, 'P1687' ) ) do
if sourceClaim.mainsnak.snaktype == 'value' then
local sourcePropertyId = sourceClaim.mainsnak.datavalue.value.id
for _, sourcePropertyClaim in pairs( getBestStatements( sourcePropertyId, 'P1630' ) ) do
if sourcePropertyClaim.mainsnak.snaktype == 'value' then
appendEntitySnaks( data.entityId, sourcePropertyId, data, 'url', {
format = function( id )
return mw.ustring.gsub( mw.ustring.gsub( sourcePropertyClaim.mainsnak.datavalue.value, '$1', id ), ' ', '%%20' )
end
} )
expandSpecialsQualifiers( data.entityId, sourcePropertyId, data )
break
end
end
end
end
end
-- do we have appropriate record in P1433 ?
local claims = findClaimsByValue( currentEntityId, 'P1343', data.sourceId )
if claims and #claims ~= 0 then
for _, claim in pairs( claims ) do
populateDataFromSnaks( claim.qualifiers, data, PROPERTY_MAP )
populateDataFromEntity( data.sourceId, data, PROPERTY_MAP )
end
end
end
---@param text string
---@param tip string
---@return string
local function toTextWithTip( text, tip )
return '<span title="' .. tip .. '" style="border-bottom: 1px dotted; cursor: help; white-space: nowrap">' .. text .. '</span>'
end
---@param lang string
---@param placeId string
---@return string
local function getPlaceName( placeId, lang )
-- ГОСТ Р 7.0.12—2011
if lang == 'ru' then
if placeId == 'Q649' then return toTextWithTip( 'М.', 'Москва' ); end
if placeId == 'Q656' then return toTextWithTip( 'СПб.', 'Санкт-Петербург' ); end
if placeId == 'Q891' then return toTextWithTip( 'Н. Новгород', 'Нижний Новгород' ); end
if placeId == 'Q908' then return toTextWithTip( 'Ростов н/Д.', 'Ростов-на-Дону' ); end
end
return nil
end
---@param data source
---@param lang string
---@return void
local function preprocessPlace( data, lang )
if not data.place then
return
end
---@type table<number, string>
local newPlace = {}
for index, place in pairs( data.place ) do
if place.id then
local newPlaceStr = getPlaceName( place.id, lang )
if newPlaceStr then
newPlace[ index ] = newPlaceStr
else
newPlace[ index ] = getLabel( place.id, lang )
end
else
newPlace[ index ] = place
end
end
data.place = newPlace
end
---@param entityId string
---@param lang string
---@param providedLabel string | nil
---@param options options
---@return string
local function getPersonNameAsLabel( entityId, lang, providedLabel, options )
-- would custom label provided we don't need to check entity at all
if not isEmpty( providedLabel ) then
return options.format( providedLabel )
end
if lang == 'mul' then
lang = i18nDefaultLanguage
end
---@type string | nil
local personName = getLabel( entityId, lang )
if isEmpty( personName ) then
return '\'\'(not translated to ' .. lang .. ')\'\''
end
if not isInstanceOf( entityId, 'Q5' ) then
return personName
end
return options.format( personName )
end
---@param entityId string
---@param lang string
---@param customLabel string | nil
---@param options options
---@return string
local function getPersonNameAsWikitext( entityId, lang, customLabel, options )
local personName = getPersonNameAsLabel( entityId, lang, customLabel, options )
local link = getElementLink( entityId, lang )
return wrapInUrl( link, personName )
end
---@param value value
---@param lang string
---@param options options
---@return string
local function getPeopleAsWikitext( value, lang, options )
if type( value ) == 'string' then
return options.format( value )
elseif type( value ) == 'table' then
if value.id then
-- this is link
if options.preferids then
return tostring( value.id )
else
if options.nolinks then
return getPersonNameAsLabel( value.id, lang, value.label, options )
else
return getPersonNameAsWikitext( value.id, lang, value.label, options )
end
end
end
local maxAuthors = 10 -- need some restrictions, as some publications have enormous amount of authors (e.g. 115 authors of Q68951544)
local resultList = {}
for _, tableValue in pairs( value ) do
local nextWikitext = getPeopleAsWikitext( tableValue, lang, options )
if not isEmpty( nextWikitext ) then
table.insert( resultList, nextWikitext )
if #resultList == maxAuthors + 1 then
-- keep one more to indicate that there are too many
break
end
end
end
local resultWikitext = ''
for i, wikitext in pairs( resultList ) do
if i == maxAuthors + 1 then
resultWikitext = resultWikitext .. ( i18nEtAl[ lang ] or i18nEtAlDefault )
break
end
if i ~= 1 then
resultWikitext = resultWikitext .. ', '
end
resultWikitext = resultWikitext .. wikitext
end
return resultWikitext
end
return '' -- options.format( '(unknown type)' )
end
---@param lang string
---@param data source
---@return string
local function generateAuthorLinks( lang, data )
local result = ''
if data.author then
result = getPeopleAsWikitext( data.author, lang, options_commas_authors )
result = '<i class="wef_low_priority_links">' .. result .. '</i> '
end
return result
end
---@param lang string
---@param data source
---@param conjunction string
---@param propertyName string
---@param urlPropertyName string?
---@return string
local function appendProperty( lang, data, conjunction, propertyName, urlPropertyName )
if not data[ propertyName ] then
return ''
end
local out
if urlPropertyName and data[ urlPropertyName ] then
out = wrapInUrl( data[ urlPropertyName ], asString( lang, data[ propertyName ], options_commas_nolinks ) )
else
out = asString( lang, data[ propertyName ], options_commas )
end
if not out or out == '' then
return ''
end
return conjunction .. out
end
---@param lang string
---@param data source
---@return string
local function appendTitle( lang, data )
local conjunction = ''
local result = ''
if data.part then
result = result .. appendProperty( lang, data, '', 'part', 'parturl' )
conjunction = ' // '
end
return result .. appendProperty( lang, data, conjunction, 'title', 'url' )
end
---@param lang string
---@return string
local function appendLanguage( lang )
if lang == i18nDefaultLanguage then
return ''
end
---@type { getRefHtml: ( fun( lang: string ): string ), list_ref: ( fun( frame: frame ): string ) }
local langs = require( 'Module:Languages' )
return langs.list_ref( p.currentFrame:newChild{ args = { lang } } )
end
---@param lang string
---@param data source
---@return string
local function appendSubtitle( lang, data )
return appendProperty( lang, data, ': ', 'subtitle', nil )
end
---@param lang string
---@param data source
---@return string
local function appendOriginalTitle( lang, data )
return appendProperty( lang, data, ' = ', 'originaltitle', nil )
end
---@param lang string
---@param data source
---@return string
local function appendPublication( lang, data )
if not data.publication then
return ''
end
local result = ' // ' .. asString( lang, data.publication.title, options_commas_it_short )
if data.publication.subtitle and data.publication.subtitle ~= '' then
result = result .. ': ' .. asString( lang, data.publication.subtitle, options_commas_it_short )
end
return result
end
---@param lang string
---@param data source
---@return string
local function appendEditor( lang, data )
if not data.editor and not data.translator then
return ''
end
local result = ' / '
if data.editor then
local prefix = i18nEditors[ lang ] or i18nEditors[ i18nDefaultLanguage ]
result = result .. prefix .. getPeopleAsWikitext( data.editor, lang, options_commas_responsible )
if data.translator then
result = result .. ', '
end
end
if data.translator then
local prefix = i18nTranslators[ lang ] or i18nTranslators[ i18nDefaultLanguage ]
result = result .. prefix .. getPeopleAsWikitext( data.translator, lang, options_commas_responsible )
end
return result
end
---@param lang string
---@param data source
local function appendEdition( lang, data )
return appendProperty( lang, data, ' — ', 'edition', nil )
end
---@param lang string
---@param data source
---@return string
local function appendPublicationData( lang, data )
if not data.place and not data.publisher and not data.year then
return ''
end
local result = ' — '
if data.place then
result = result .. asString( lang, data.place, options_commas_short )
if data.publisher or data.year then
result = result .. ': '
end
end
if data.publisher then
result = result .. asString( lang, data.publisher, options_commas_short )
if data.year then
result = result .. ', '
end
end
if data.year then
result = result .. asString( lang, data.year, options_commas )
end
result = result .. '.'
return result
end
---@param lang string
---@param data source
---@return string
local function appendVolumeAndIssue( lang, data )
if not data.volume and not data.issue then
return ''
end
local result = ' — '
local letter_vol = i18nVolume[ lang ] or i18nVolume[ i18nDefaultLanguage ]
local letter_iss = i18nIssue[ lang ] or i18nIssue[ i18nDefaultLanguage ]
if data.volume then
result = result .. appendProperty( lang, data, letter_vol .. ' ', 'volume', nil )
result = result ..appendProperty( lang, data, ', ' .. letter_iss .. ' ', 'issue', nil )
else
result = result .. appendProperty( lang, data, letter_iss .. ' ', 'issue', nil )
end
result = result .. '.'
return result
end
---@param lang string
---@param data source
---@return string
local function appendPages( lang, data )
if not data.pages then
return ''
end
local letter = i18nPages[ lang ] or i18nPages[ i18nDefaultLanguage ]
local strPages = asString( lang, data.pages, options_commas )
strPages = mw.ustring.gsub( strPages, '[-—]', '—' )
return ' — ' .. letter .. ' ' .. strPages .. '.'
end
---@param lang string
---@param data source
---@return string
local function appendNumberOfPages( lang, data )
if not data.numberOfPages then
return ''
end
local letter = i18nNumberOfPages[ lang ] or i18nNumberOfPages[ i18nDefaultLanguage ]
return appendProperty( lang, data, ' — ', 'numberOfPages', nil ) .. ' ' .. letter
end
---@param lang string
---@param data source
---@return string
local function appendBookSeries( lang, data )
if not data.bookSeries then
return ''
end
local result = appendProperty( lang, data, ' — (', 'bookSeries', nil )
if data.bookSeriesVolume or data.bookSeriesIssue then
result = result .. '; '
local letter_vol = i18nVolume[ lang ] or i18nVolume[ i18nDefaultLanguage ]
local letter_iss = i18nIssue[ lang ] or i18nIssue[ i18nDefaultLanguage ]
if data.bookSeriesVolume then
result = result .. appendProperty( lang, data, letter_vol .. ' ', 'bookSeriesVolume', nil )
result = result .. appendProperty( lang, data, ', ' .. letter_iss .. ' ', 'bookSeriesIssue', nil )
else
result = result .. appendProperty( lang, data, letter_iss .. ' ', 'bookSeriesIssue', nil )
end
end
result = result .. ')'
return result
end
---@param lang string
---@param data source
---@return string
local function appendTirage( lang, data )
if not data.tirage then
return ''
end
local tirageTemplate = i18nTirage[ lang ] or i18nTirage[ i18nDefaultLanguage ]
---@type options
local optionsTirage = {
separator = '; ',
conjunction = '; ',
format = function( _data ) return tostring( mw.ustring.format( tirageTemplate, _data ) ) end,
short = false,
nolinks = false,
preferids = false,
}
return ' — ' .. asString( lang, data.tirage, optionsTirage )
end
---@param lang string
---@param value string | nil
---@param options options
---@param prefix string?
---@return string
local function appendIdentifier( lang, value, options, prefix )
if not value then
return ''
end
return ' — ' .. ( prefix or '' ) .. asString( lang, value, options )
end
---@param result string
---@param lang string
---@param data source
---@return string
local function wrapSourceId( result, lang, data )
if not data.sourceId then
return result
end
local citeType = data.type and asString( lang, data.type, options_citetypes ) or 'citetype_unknown'
return '<span class="wikidata_cite ' .. citeType .. '" data-entity-id="' .. data.sourceId .. '">' .. result .. '</span>'
end
---@param data source
---@return string
local function appendAccessDate( data )
if not data.accessdate then
return ''
end
local date = getSingle( data.accessdate )
local pattern = "(%-?%d+)%-(%d+)%-(%d+)T"
local y, m, d = mw.ustring.match( date, pattern )
y, m, d = tonumber( y ), tonumber( m ), tonumber( d )
local date_str = ( d > 0 and ' ' .. tostring( d ) or '' )
.. ( m > 0 and ' ' .. monthGen[ m ] or '' )
.. ( y > 0 and ' ' .. tostring( y ) or '' )
return " <small>Проверено" .. date_str .. ".</small>"
end
---@param data source
---@param lang string
---@return void
local function populateUrl( data, lang )
if data.sourceId and not data.url then
local sitelink = getSitelink( data.sourceId, lang .. 'wikisource' )
if sitelink then
data.url = ':' .. lang .. ':s:' .. sitelink
end
end
end
---@param data source
---@return void
local function populateYear( data )
if not data.year and data.dateOfPublication then
local date = getSingle( data.dateOfPublication )
data.year = mw.ustring.sub( date, 2, 5 )
end
if not data.year and data.dateOfCreation then
local date = getSingle( data.dateOfCreation )
data.year = mw.ustring.sub( date, 2, 5 )
end
end
---@param data source
---@return void
local function populateTitle( data )
data.title = data.title or getSingle( data.url )
end
---@param data source
---@return string
local function renderSource( data )
local lang = getLangCode( data.lang ) or i18nDefaultLanguage
preprocessPlace( data, lang )
populateUrl( data, lang )
populateTitle( data )
if not data.title then
return ''
end
populateYear( data )
local result = generateAuthorLinks( lang, data )
result = result .. appendTitle( lang, data )
result = result .. appendLanguage( lang )
result = result .. appendSubtitle( lang, data )
result = result .. appendOriginalTitle( lang, data )
result = result .. appendPublication( lang, data )
result = result .. '<span class="wef_low_priority_links">'
result = result .. appendEditor( lang, data ) -- Might take current editor instead of actual. Use with caution
result = result .. appendEdition( lang, data )
result = result .. appendPublicationData( lang, data )
result = result .. appendVolumeAndIssue( lang, data )
result = result .. appendPages( lang, data )
result = result .. appendNumberOfPages( lang, data )
result = result .. appendBookSeries( lang, data )
result = result .. appendTirage( lang, data )
result = result .. appendIdentifier( lang, data.isbn, options_commas, 'ISBN ' )
result = result .. appendIdentifier( lang, data.issn, options_issn, 'ISSN ' )
result = result .. appendIdentifier( lang, data.doi, options_doi, nil )
result = result .. appendIdentifier( lang, data.pmid, options_pmid, nil )
result = result .. appendIdentifier( lang, data.arxiv, options_arxiv, nil )
result = result .. appendAccessDate( data )
result = result .. '</span>'
return wrapSourceId( result, lang, data )
end
---@param data source Данные в простом формате, согласованном с модулями формирования библиографического описания
---@param snaks snaks
---@return string | nil
local function renderReferenceImpl( data, snaks )
-- не показывать источники с "импортировано из"
if snaks.P143 then
return nil
end
-- забрать данные из reference
populateDataFromSnaks( snaks or {}, data, PROPERTY_MAP )
data.sourceId = getSingle( data.sourceId )
populateDataFromEntity( data.sourceId, data, PROPERTY_MAP )
expandSpecials( data )
populateSourceDataImpl( data.sourceId, data, PROPERTY_MAP )
expandPublication( data )
expandBookSeries( data )
if next( data ) == nil then
return nil
end
local rendered = renderSource( data )
if mw.ustring.len( rendered ) == 0 then
return nil
end
if data.ref then
local anchorValue = 'CITEREF' .. data.ref .. ( coalesce( { data[ 'ref-year' ], data.year } ) or '' )
rendered = '<span class="citation" id="' .. mw.uri.anchorEncode( anchorValue ) .. '">' .. rendered .. '</span>'
end
return rendered
end
---@param frame frame
---@param currentEntityId string | { id: string }
---@param reference table{ snaks: snaks }
---@return string | nil
function p.renderSource( frame, currentEntityId, reference )
reference = reference or { snaks = {} }
p.currentFrame = frame
local data = getFilledArgs( frame.args or {} )
populateDataFromSnaks( reference.snaks, data, PROPERTY_MAP )
data.sourceId = getSingle( data.sourceId )
if not currentEntityId then
data.entityId = mw.wikibase.getEntityIdForCurrentPage()
elseif type( currentEntityId ) == 'string' then
data.entityId = currentEntityId
elseif type( currentEntityId ) == 'table' and currentEntityId.id then
data.entityId = currentEntityId.id
end
---@type string
local rendered = renderReferenceImpl( data, reference.snaks or {} )
if not rendered then
return ''
end
return rendered
end
---@param frame frame
---@param currentEntityId string
---@param reference table
---@return string
function p.renderReference( frame, currentEntityId, reference )
local rendered = p.renderSource( frame, currentEntityId, reference )
if not rendered or rendered == '' then
return ''
end
-- Про выбор алгоритма хеширования см. [[Модуль:Hash]]. Знак подчёркивания в начале позволяет
-- исключить ошибку, когда имя сноски — чисто числовое значение, каковыми иногда бывают хеши.
return frame:extensionTag( 'ref', rendered, { name = '_' .. mw.hash.hashValue( 'fnv164', rendered ) } ) .. '[[Category:Википедия:Статьи с источниками из Викиданных]]'
end
---@param frame frame
---@return string | nil
function p.testPersonNameToAuthorName( frame )
return personNameToAuthorName( frame.args[ 1 ] )
end
---@param frame frame
---@return string | nil
function p.testPersonNameToResponsibleName( frame )
return personNameToResponsibleName( frame.args[ 1 ] )
end
return p
752a204827a41ecd6cf518bdb22da12718bca2ec
Модуль:WikidataSelectors
828
141
325
324
2024-08-10T15:21:03Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
local i18n = {
["errors"] = {
["rank-not-valid"] = "Некорретное значение приоритета (rank)",
["cant-parse-condition"] = "Не удалось разобрать условие"
}
}
local validRanks = {
'best',
'preferred',
'normal',
'deprecated'
}
--[[
Internal function for error message
Input: key in errors table
Output: error message
]]
local function throwError( key )
error( i18n.errors[key] )
end
local p = {}
--[[
Load property and filter statements
Input: entityId, selector string
Output: filtered statements table
]]
function p.load( entityId, propertySelector )
local propertyId = mw.ustring.match( propertySelector, '^[Pp]%d+' )
if not propertyId then
return nil
end
propertyId = string.upper( propertyId )
local allStatements = {}
allStatements[ propertyId ] = mw.wikibase.getAllStatements( entityId, propertyId )
return p.filter( allStatements, propertySelector )
end
--[[
Parse selectors and filter statements
Input: statements table, selector string
Output: filtered statements table
]]
function p.filter( allClaims, propertySelector )
propertySelector = mw.text.trim( propertySelector )
-- Get property ID from selector
local propertyId = mw.ustring.match( propertySelector, '^[Pp]%d+' )
if not propertyId then
propertyId = ''
end
local initPos = #propertyId + 1
propertyId = string.upper( propertyId )
if ( not allClaims ) then
return nil
end
local allPropertyClaims = allClaims[propertyId]
if ( not allPropertyClaims ) then
return nil
end
-- Gathering rules
local rules = p.matchSelectors( propertySelector, initPos )
-- If there is no rank filter, than default rank is 'best'
local isRanked = false
for i, subRules in ipairs( rules ) do
for j, rule in ipairs( subRules ) do
if rule['type'] == 'rank' then
isRanked = true
break
end
end
end
if not isRanked then
table.insert( rules, 1, { { type = 'rank', value = 'best' } } )
end
-- Execute rules
allPropertyClaims = p.applyRules( allPropertyClaims, rules )
return allPropertyClaims
end
--[[
Match and gather selector rules
Input: string with selectors rules, start position
Output: rules table
]]
function p.matchSelectors( selectorsString, initPos )
local rules = {}
local rawRulePattern = '^%s*%[%s*[^%[%]]+%s*%]%s*'
local rulePattern = '^%s*%[%s*([^%[%]]+)%s*%]%s*$'
if not initPos then
initPos = 1
end
local rawRule = mw.ustring.match( selectorsString, rawRulePattern, initPos )
while rawRule do
initPos = initPos + #rawRule
rule = mw.ustring.match( rawRule, rulePattern )
rule = mw.text.trim( rule )
local subRules = mw.text.split( rule, '%s*,%s*' )
local commands = {}
local comm
for i, subRule in ipairs( subRules ) do
local isInversed = false
if mw.ustring.match( subRule, '^!' ) then
isInversed = true
subRule = mw.ustring.match( subRule, '^!%s*(.+)$' )
end
-- p123[1]
if mw.ustring.match( subRule, '^%d+$' ) then
table.insert( commands, {
type = 'position',
value = subRule,
inversed = isInversed
} )
-- p123[rank:preferred]
elseif mw.ustring.match( subRule, '^rank%s*:%s*(%a+)$' ) then
rank = mw.ustring.match( subRule, '^rank%s*:%s*(%a+)$' )
table.insert( commands, {
type = 'rank',
value = rank,
inversed = isInversed
} )
-- p123[language:xx]
elseif mw.ustring.match( subRule, '^language%s*:%s*([%a%-]+)$' ) then
value = mw.ustring.match( subRule, '^language%s*:%s*([%a%-]+)$' )
table.insert( commands, {
type = 'language',
value = value,
inversed = isInversed
} )
-- p123[language!:xx]
elseif mw.ustring.match( subRule, '^language%s*!:%s*([%a%-]+)$' ) then
value = mw.ustring.match( subRule, '^language%s*!:%s*([%a%-]+)$' )
table.insert( commands, {
type = 'language',
value = value,
inversed = not isInversed
} )
-- p123[min]
elseif mw.ustring.match( subRule, '^min$' ) then
table.insert( commands, { type = 'value_min' } )
-- p123[max]
elseif mw.ustring.match( subRule, '^max$' ) then
table.insert( commands, { type = 'value_max' } )
-- p123[min:p456]
elseif mw.ustring.match( subRule, '^min%s*:%s*[Pp]%d+$' ) then
value = mw.ustring.match( subRule, ':%s*([Pp]%d+)$' )
table.insert( commands, {
type = 'qualifier_min',
qualifier = value
} )
-- p123[max:p456]
elseif mw.ustring.match( subRule, '^max%s*:%s*[Pp]%d+$' ) then
value = mw.ustring.match( subRule, ':%s*([Pp]%d+)$' )
table.insert( commands, {
type = 'qualifier_max',
qualifier = value
} )
-- p123[unit:q789]
elseif mw.ustring.match( subRule, '^unit%s*:%s*[^%[%],:]+$' ) then
value = mw.ustring.match( subRule, ':%s*([^%[%],:]+)$' )
table.insert( commands, {
type = 'unit',
value = value,
inversed = isInversed
} )
-- p123[unit!:q789]
elseif mw.ustring.match( subRule, '^unit%s*!:%s*[^%[%],:]+$' ) then
value = mw.ustring.match( subRule, '!:%s*([^%[%],:]+)$' )
table.insert( commands, {
type = 'unit',
value = value,
inversed = not isInversed
} )
-- p123[p456]
elseif mw.ustring.match( subRule, '^[Pp]%d+$' ) then
qualifier = mw.ustring.match( subRule, '^[Pp]%d+' )
table.insert( commands, {
type = 'qualifier',
qualifier = qualifier,
value = nil,
inversed = isInversed
} )
-- p123[p456:q789]
elseif mw.ustring.match( subRule, '^[Pp]%d+%s*:%s*[^%[%],:]+$' ) then
qualifier = mw.ustring.match( subRule, '^([Pp]%d+)%s*:?' )
value = mw.ustring.match( subRule, ':%s*([^%[%],:]+)$' )
table.insert( commands, {
type = 'qualifier',
qualifier = qualifier,
value = value,
inversed = isInversed
} )
-- p123[p456!:q789]
elseif mw.ustring.match( subRule, '^[Pp]%d+%s*!:%s*[^%[%],:]+$' ) then
qualifier = mw.ustring.match( subRule, '^([Pp]%d+)%s*!:?' )
value = mw.ustring.match( subRule, '!:%s*([^%[%],:]+)$' )
table.insert( commands, {
type = 'qualifier',
qualifier = qualifier,
value = value,
inversed = not isInversed
} )
-- p123[q456]
elseif mw.ustring.match( subRule, '^[Qq]%d+$' ) then
value = mw.ustring.match( subRule, '^[Qq]%d+' )
table.insert( commands, {
type = 'value',
value = value,
inversed = isInversed
} )
else
throwError( 'cant-parse-condition' )
end
end
if #commands then
table.insert( rules, commands )
end
rawRule = mw.ustring.match( selectorsString, rawRulePattern, initPos )
end
return rules
end
--[[
Intercept statements with selector rules
Input: statements table, selector rules
Output: filtered statements table
]]
function p.applyRules( claims, rules )
for i, subRules in ipairs( rules ) do
local newClaims = {}
for j, rule in ipairs( subRules ) do
if rule['type'] == 'rank' then
table.insert( newClaims, p.filterByRank( claims, rule['value'], rule['inversed'] ) )
elseif rule['type'] == 'language' then
table.insert( newClaims, p.filterByLanguage( claims, rule['value'], rule['inversed'] ) )
elseif rule['type'] == 'unit' then
table.insert( newClaims, p.filterByUnit( claims, rule['value'], rule['inversed'] ) )
elseif rule['type'] == 'position' then
table.insert( newClaims, p.filterByPosition( claims, rule['value'], rule['inversed'] ) )
elseif rule['type'] == 'qualifier' then
table.insert( newClaims, p.filterByQualifier( claims, rule['qualifier'], rule['value'], rule['inversed'] ) )
elseif rule['type'] == 'qualifier_min' then
table.insert( newClaims, p.filterUtterByQualifier( claims, rule['qualifier'], true ) )
elseif rule['type'] == 'qualifier_max' then
table.insert( newClaims, p.filterUtterByQualifier( claims, rule['qualifier'], false ) )
elseif rule['type'] == 'value' then
table.insert( newClaims, p.filterByValue( claims, rule['value'], rule['inversed'] ) )
elseif rule['type'] == 'value_min' then
table.insert( newClaims, p.filterUtter( claims, true ) )
elseif rule['type'] == 'value_max' then
table.insert( newClaims, p.filterUtter( claims, false ) )
end
end
claims = {}
--[[
Merge all claims
TODO: It's not good
]]
for j, newSubClaims in ipairs( newClaims ) do
for k, newClaim in ipairs( newSubClaims ) do
local isNew = true
for l, oldClaim in ipairs( claims ) do
if oldClaim['id'] == newClaim['id'] then
isNew = false
break
end
end
if isNew then
table.insert( claims, newClaim )
end
end
end
end
return claims
end
--[[
Filter statements by rank
Input: claims table, rank value, inversion
Output: filtered statements table
]]
function p.filterByRank( claims, rank, inversed )
if not inversed then
inversed = false
end
if not rank then
rank = 'best'
end
-- Check if rank value is valid
local isValidRank = false
for i, validRank in ipairs( validRanks ) do
if rank == validRank then
isValidRank = true
break
end
end
if not isValidRank then
throwError( 'rank-not-valid' )
end
-- Find the best rank
if rank == 'best' then
rank = 'normal' -- default rank (don't use deprecated even if it's no more claims)
-- If we have at least one preferred rank, mark it as best
for i, statement in pairs( claims ) do
if (statement.rank == 'preferred') then
rank = 'preferred'
break
end
end
end
local resultClaims = {};
for i, statement in pairs( claims ) do
if ( statement.rank == rank ) ~= inversed then
table.insert( resultClaims, statement )
end
end
return resultClaims
end
--[[
Filter statements by language of value
Input: claims table, language, inversion
Output: filtered statements table
]]
function p.filterByLanguage( claims, language, inversed )
if not inversed then
inversed = false
end
local resultClaims = {}
local mulStatement = {}
for i, statement in ipairs( claims ) do
isMatchLanguage = false
if statement['mainsnak']
and statement['mainsnak']['datavalue']
and statement['mainsnak']['datavalue']['value']
and statement['mainsnak']['datavalue']['value']['language'] then
if statement['mainsnak']['datavalue']['value']['language'] == language then
isMatchLanguage = true
end
if statement['mainsnak']['datavalue']['value']['language'] == 'mul' then
mulStatement = statement
end
end
if isMatchLanguage ~= inversed then
table.insert( resultClaims, statement )
end
end
if next(resultClaims) == nil and next(mulStatement) ~= nil then
-- if specific language is not found, but there is Q20923490 value
table.insert( resultClaims, mulStatement )
end
return resultClaims
end
--[[
Filter statements by unit of value
Input: claims table, unit, inversion
Output: filtered statements table
]]
function p.filterByUnit( claims, unit, inversed )
if not inversed then
inversed = false
end
unit = 'http://www.wikidata.org/entity/' .. string.upper( unit )
local resultClaims = {}
for i, statement in ipairs( claims ) do
isMatchUnit = false
if statement['mainsnak']
and statement['mainsnak']['datavalue']
and statement['mainsnak']['datavalue']['value']
and statement['mainsnak']['datavalue']['value']['unit']
and statement['mainsnak']['datavalue']['value']['unit'] == unit then
isMatchUnit = true
end
if isMatchUnit ~= inversed then
table.insert( resultClaims, statement )
break
end
end
return resultClaims
end
--[[
Filter statements by position
Input: claims table, position, inversion
Output: filtered statements table
]]
function p.filterByPosition( claims, position, inversed )
if not inversed then
inversed = false
end
local resultClaims = {};
for statementPosition, statement in ipairs( claims ) do
if ( statementPosition == tonumber( position ) ) ~= inversed then
table.insert( resultClaims, statement )
break
end
end
return resultClaims
end
--[[
Filter statements by qualifier existance or it's value
Input: claims table, ID of qualifier's property, qualifier's value, inversion
Output: filtered statements table
]]
function p.filterByQualifier( claims, qualifierId, value, inversed )
if not inversed then
inversed = false
end
qualifierId = string.upper( qualifierId )
local resultClaims = {}
for i, statement in ipairs( claims ) do
if statement['qualifiers'] and statement['qualifiers'][qualifierId] then
if value == nil then
if ( #statement['qualifiers'][qualifierId] > 0 ) ~= inversed then
table.insert( resultClaims, statement )
end
else
local isQualifierFound = false
for j, qualifier in ipairs( statement['qualifiers'][qualifierId] ) do
if qualifier['datavalue'] then
local qualifierValue = qualifier['datavalue']['value']
if qualifier['datavalue']['type'] == 'wikibase-entityid' then
qualifierValue = qualifierValue.id
value = string.upper( value )
end
if qualifierValue == value then
isQualifierFound = true
break
end
end
end
if isQualifierFound ~= inversed then
table.insert( resultClaims, statement )
end
end
elseif inversed then
table.insert( resultClaims, statement )
end
end
return resultClaims
end
--[[
Filter statements by it's values
Input: claims table, value, inversed
Output: filtered statements table
]]
function p.filterByValue( claims, value, inversed )
inversed = inversed or false
local resultClaims = {}
for i, statement in ipairs( claims ) do
local statementValue
if statement['mainsnak']
and statement['mainsnak']['datavalue']
and statement['mainsnak']['datavalue']['type']
then
statementValue = statement['mainsnak']['datavalue']['value']
if statement['mainsnak']['datavalue']['type'] == 'quantity' then
statementValue = statementValue.amount
end
if statement['mainsnak']['datavalue']['type'] == 'time' then
statementValue = statementValue.time
end
if statement['mainsnak']['datavalue']['type'] == 'wikibase-entityid' then
statementValue = statementValue.id
value = string.upper( value )
end
end
if ( statementValue == value ) ~= inversed then
table.insert( resultClaims, statement )
end
end
return resultClaims
end
--[[
Find a statement with minimum or maximum value
Input: claims table, asc, inversed
Output: filtered statements table
]]
function p.filterUtter( claims, asc, inversed )
local resultValue = nil
for i, statement in ipairs( claims ) do
local statementValue
if statement['mainsnak'] and
statement['mainsnak']['datavalue'] and
statement['mainsnak']['datavalue']['type']
then
statementValue = statement['mainsnak']['datavalue']['value']
if statement['mainsnak']['datavalue']['type'] == 'quantity' then
statementValue = statementValue.amount
end
if statement['mainsnak']['datavalue']['type'] == 'time' then
statementValue = statementValue.time
end
if statement['mainsnak']['datavalue']['type'] == 'wikibase-entityid' then
statementValue = statementValue.id
end
if not resultValue or ( statementValue < resultValue ) == asc then
resultValue = statementValue
end
end
end
mw.logObject( resultValue, 'resultValue' )
return p.filterByValue( claims, resultValue, inversed )
end
--[[
Find a statement with minimum or maximum qualifier value
Input: claims table, qualifierId, asc
Output: filtered statements table
]]
function p.filterUtterByQualifier( claims, qualifierId, asc )
qualifierId = string.upper( qualifierId )
local resultValue = nil
local resultStatement = nil
for i, statement in ipairs( claims ) do
if not statement['qualifiers'] and not statement['qualifiers'][qualifierId] then
if resultStatement == nil then
resultStatement = statement
end
else
for _, qualifier in ipairs( statement['qualifiers'][qualifierId] ) do
if qualifier['datavalue'] then
local qualifierValue = qualifier['datavalue']['value']
if qualifier['datavalue']['type'] == 'quantity' then
qualifierValue = qualifierValue.amount
end
if qualifier['datavalue']['type'] == 'time' then
qualifierValue = qualifierValue.time
end
if qualifier['datavalue']['type'] == 'wikibase-entityid' then
qualifierValue = qualifierValue.id
end
if not resultValue or ( qualifierValue < resultValue ) == asc then
resultStatement = statement
resultValue = qualifierValue
end
end
end
end
end
return { resultStatement }
end
return p
0bdff3a63bf171160cdec5c966211fbbf3003880
Модуль:Wikidata/config
828
142
327
326
2024-08-10T15:21:03Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
-- Property configuration for Wikidata module
return {
global = {
separator = ', ',
conjunction = ' и ',
},
presets = {
['catonly'] = {
datatype = 'wikibase-item',
conjunction = '',
invisible = true,
['value-module'] = 'Wikidata/item',
['value-function'] = 'formatCategoryOnly',
references = '',
category = 'P910',
},
['country'] = {
datatype = 'wikibase-item',
['claim-module'] = 'Wikidata/Places',
['claim-function'] = 'formatCountryClaimWithFlag',
before = '<ul><li>',
separator = '</li><li>',
conjunction = '</li><li>',
after = '</li></ul>',
},
['from-to'] = {
datatype = 'time',
['property-module'] = 'Wikidata/date',
['property-function'] = 'formatDateIntervalProperty',
},
['link'] = {
['value-module'] = 'Wikidata/link',
['value-function'] = 'fromModule',
},
['list'] = {
before = '<ul><li>',
separator = '</li><li>',
conjunction = '</li><li>',
after = '</li></ul>',
},
['name'] = {
datatype = 'monolingualtext',
monolingualLangTemplate = 'lang',
separator = '<br>',
conjunction = '<br>',
},
['place'] = {
datatype = 'wikibase-item',
['claim-module'] = 'Wikidata/Places',
['claim-function'] = 'formatPlaceWithQualifiers',
before = '<ul><li>',
separator = '</li><li>',
conjunction = '</li><li>',
after = '</li></ul>',
},
['quantity (date)'] = {
datatype = 'quantity',
before = '<ul><li>',
separator = '</li><li>',
conjunction = '</li><li>',
after = '</li></ul>',
qualifier = 'P585',
},
},
datatypes = {
commonsMedia = {
limit = 1,
references = false,
size = '274x400px',
separator = '<br>',
conjunction = '<br>',
somevalue = '',
['value-module'] = 'Wikidata/media',
['value-function'] = 'formatCommonsMediaValue',
},
['external-id'] = {
references = false,
},
['globe-coordinate'] = {
limit = 1,
references = false,
},
url = {
separator = '<br>',
conjunction = '<br>',
references = false,
['value-module'] = 'Wikidata/url',
['value-function'] = 'formatUrlValue',
},
quantity = {
siConversion = true
}
},
properties = {
P6 = { datatype = 'wikibase-item', },
P17 = {
preset = 'country',
},
P18 = {
datatype = 'commonsMedia',
fixdouble = true,
},
P19 = {
preset = 'place',
separator = ',</li><li>',
conjunction = ' или </li><li>',
},
P20 = {
preset = 'place',
separator = ',</li><li>',
conjunction = ' или </li><li>',
},
P22 = {
datatype = 'wikibase-item',
conjunction = ' или '
},
P25 = {
datatype = 'wikibase-item',
conjunction = ' или '
},
P26 = { datatype = 'wikibase-item', },
P27 = {
preset = 'country',
},
P31 = {
datatype = 'wikibase-item',
references = false,
},
P37 = { datatype = 'wikibase-item', },
P39 = {
datatype = 'wikibase-item',
['claim-module'] = 'Wikidata/positions',
['claim-function'] = 'formatPositionClaim',
separator = '',
conjunction = '',
allowTables = true,
},
P40 = { datatype = 'wikibase-item', },
P41 = {
datatype = 'commonsMedia',
size = '150x200px',
},
P53 = {
datatype = 'wikibase-item',
category = 'P910',
},
P54 = {
category = 'P6112',
},
P57 = {
datatype = 'wikibase-item',
preset = 'list',
},
P58 = {
datatype = 'wikibase-item',
preset = 'list',
},
P59 = {
datatype = 'wikibase-item',
category = 'P910',
references = false,
},
P69 = {
datatype = 'wikibase-item',
preset = 'list',
category = 'P3876',
qualifier = 'P582',
},
P94 = {
datatype = 'commonsMedia',
size = '100x200px',
},
P86 = {
datatype = 'wikibase-item',
preset = 'list',
},
P101 = { datatype = 'wikibase-item', },
P102 = {
datatype = 'wikibase-item',
preset = 'list',
qualifier = 'P582',
category = 'P6365',
},
P103 = { datatype = 'wikibase-item', },
P106 = {
datatype = 'wikibase-item',
['claim-module'] = 'Wikidata/item',
['claim-function'] = 'formatEntityWithGenderClaim',
conjunction = ', ',
},
P108 = {
datatype = 'wikibase-item',
preset = 'list',
category = 'P4195',
},
P109 = {
datatype = 'commonsMedia',
size = '150x150px',
alt = 'Изображение автографа',
},
P117 = {
datatype = 'commonsMedia',
size = '290x300px',
alt = 'Изображение химической структуры',
},
P119 = {
preset = 'place',
thisLocationOnly = 'true',
},
P131 = { datatype = 'wikibase-item', },
P140 = {
datatype = 'wikibase-item',
},
P154 = {
size = '220x80px',
alt = 'Изображение логотипа',
},
P159 = {
preset = 'place',
},
P161 = {
preset = 'list',
},
P162 = {
preset = 'list',
},
P163 = { datatype = 'wikibase-item', },
P166 = {
datatype = 'wikibase-item',
['property-module'] = 'Wikidata/Medals',
['property-function'] = 'formatProperty',
['value-module'] = 'Wikidata/Medals',
['value-function'] = 'formatValue',
before = '<div style="text-align:justify">',
after = '</div>',
separator = ' ',
conjunction = ' ',
references = false,
allowTables = true,
},
P190 = { datatype = 'wikibase-item', },
P212 = {
preset = 'link',
},
P225 = {
preset = 'list',
['claim-module'] = 'Wikidata/Biology',
['claim-function'] = 'formatTaxonNameClaim',
},
P237 = { datatype = 'wikibase-item', },
P241 = { datatype = 'wikibase-item', },
P242 = {
datatype = 'commonsMedia',
size = '300x300px',
},
P247 = {
formatter = 'https://nssdc.gsfc.nasa.gov/nmc/spacecraft/display.action?id=$1',
},
P267 = {
preset = 'link',
},
P276 = {
preset = 'place',
},
P281 = { datatype = 'string', },
P286 = {
preset = 'list',
},
P296 = {
formatter = 'http://osm.sbin.ru/esr/esr:$1',
},
P301 = {
rawArticle = true,
},
P344 = {
preset = 'list',
},
P345 = {
preset = 'link',
},
P348 = {
preset = 'list',
['property-module'] = 'Wikidata/Software',
['property-function'] = 'formatVersionProperty',
},
P361 = { datatype = 'wikibase-item', },
P373 = {
datatype = 'string',
['value-module'] = 'Wikidata/media',
['value-function'] = 'formatCommonsCategory',
limit = 1,
},
P374 = { datatype = 'external-id', },
P395 = { datatype = 'string', },
P407 = { datatype = 'wikibase-item', },
P410 = { datatype = 'wikibase-item', },
P412 = {
datatype = 'wikibase-item',
category = 'P910',
},
P413 = {
datatype = 'wikibase-item',
['claim-module'] = 'Wikidata/item',
['claim-function'] = 'formatEntityWithGenderClaim',
conjunction = ', ',
category = 'P910',
},
P414 = {
['claim-module'] = 'Wikidata/item',
['claim-function'] = 'applyDefaultTemplate',
},
P421 = { datatype = 'wikibase-item', },
P473 = { datatype = 'string', },
P495 = {
preset = 'country',
},
P505 = {
preset = 'list',
},
P512 = {
datatype = 'wikibase-item',
['property-module'] = 'Wikidata/P512',
['property-function'] = 'formatAcademicDegree',
},
P527 = {
preset = 'list',
},
P528 = {
references = false,
qualifier = 'P972',
},
P551 = {
preset = 'place',
},
P569 = {
datatype = 'time',
['claim-module'] = 'Wikidata/date',
['claim-function'] = 'formatDateOfBirthClaim',
},
P570 = {
datatype = 'time',
['claim-module'] = 'Wikidata/date',
['claim-function'] = 'formatDateOfDeathClaim',
},
P571 = { datatype = 'time', },
P576 = { datatype = 'time', },
P598 = { datatype = 'wikibase-item', },
P607 = {
datatype = 'wikibase-item',
preset = 'list',
},
P625 = { datatype = 'globe-coordinate', },
P669 = {
qualifier = 'P670',
},
P685 = {
formatter = 'https://www.ncbi.nlm.nih.gov/Taxonomy/Browser/wwwtax.cgi?mode=Info&id=$1',
},
P721 = {
preset = 'link',
},
P764 = {
preset = 'link',
},
P803 = { datatype = 'wikibase-item', },
P856 = { datatype = 'url', },
P881 = {
novalue = 'нет',
category = 'P910',
},
P884 = {
preset = 'link',
},
P915 = {
category = 'P1740',
},
P957 = {
preset = 'link',
},
P972 = {
preset = 'catonly',
},
P1077 = {
preset = 'link',
},
P1082 = {
preset = 'quantity (date)',
unit = 'чел.',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator'
},
P1098 = {
preset = 'quantity (date)',
unit = 'чел.',
},
P1120 = {
preset = 'quantity (date)',
unit = 'чел.',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator'
},
P1128 = {
datatype = 'quantity',
preset = 'quantity (date)',
unit = 'чел.',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator'
},
P1114 = {
datatype = 'quantity',
qualifier = 'P585',
},
P1174 = {
preset = 'quantity (date)',
unit = 'чел.',
},
P1195 = {
['value-module'] = 'Wikidata/Software',
['value-function'] = 'formatExtension',
conjunction = ' или ',
},
P1215 = {
datatype = 'quantity',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatVisualMagnitude'
},
P1246 = {
preset = 'link',
},
P1249 = { datatype = 'time', },
P1352 = { preset = 'quantity (date)', },
P1376 = { datatype = 'wikibase-item', },
P1402 = {
preset = 'link',
},
P1448 = {
preset = 'name',
},
P1458 = {
datatype = 'quantity',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatColorIndex'
},
P1464 = { datatype = 'wikibase-item', },
P1476 = {
preset = 'name',
},
P1477 = {
preset = 'name',
},
P1532 = {
preset = 'country',
rank = '[rank:normal, rank:preferred]',
},
P1543 = {
datatype = 'commonsMedia',
},
P1559 = {
preset = 'name',
},
P1603 = {
preset = 'quantity (date)',
unit = 'чел.',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator'
},
P1621 = {
size = '300x300px',
},
P1692 = {
preset = 'link',
},
P1705 = {
preset = 'name',
},
P1753 = {
rowArticle = true,
},
P1809 = {
preset = 'list',
},
P1846 = {
datatype = 'commonsMedia',
fixdouble = true,
},
P2031 = {
preset = 'from-to',
to = 'P2032',
within = 'P570',
},
P2043 = {
preset = 'quantity (date)',
},
P2044 = { datatype = 'quantity', },
P2046 = {
preset = 'quantity (date)',
siConversion = false,
},
P2047 = {
siConversion = false,
},
P2048 = {
conjunction = ' или ',
},
P2060 = {
siConversion = false,
},
P2097 = {
siConversion = false,
},
P2120 = {
siConversion = false,
},
P2137 = {
preset = 'quantity (date)',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator',
countByThousands = true,
},
P2139 = {
preset = 'quantity (date)',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator',
countByThousands = true,
},
P2146 = {
siConversion = false,
},
P2214 = {
siConversion = false
},
P2226 = {
preset = 'quantity (date)',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator',
countByThousands = true,
},
P2257 = {
siConversion = false
},
P2260 = {
siConversion = false
},
P2295 = {
preset = 'quantity (date)',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator',
countByThousands = true,
},
P2324 = {
datatype = 'quantity',
preset = 'quantity (date)',
unit = 'чел.'
},
P2403 = {
preset = 'quantity (date)',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator',
countByThousands = true,
},
P2425 = {
alt = 'Изображение орденской планки',
},
P2583 = {
siConversion = false,
},
P2597 = {
preset = 'catonly',
},
P2650 = { datatype = 'wikibase-item', },
P2789 = {
preset = 'list',
},
P2896 = {
siConversion = false,
},
P2910 = {
size = '100x80px',
},
P3083 = {
formatter = 'http://simbad.u-strasbg.fr/simbad/sim-id?Ident=$1',
},
P3086 = {
siConversion = false,
},
P3362 = {
preset = 'quantity (date)',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator',
countByThousands = true,
},
P4614 = {
category = 'P1200',
},
P5348 = {
siConversion = false,
},
P6257 = {
['value-module'] = 'Wikidata/number',
['value-function'] = 'formatRA',
},
P6258 = {
['value-module'] = 'Wikidata/number',
['value-function'] = 'formatDMS',
},
P6259 = {
['references'] = false,
},
P7584 = {
siConversion = false,
},
P8010 = {
datatype = 'quantity',
preset = 'quantity (date)',
unit = 'чел.',
['property-module'] = 'Wikidata/number',
['property-function'] = 'formatPropertyWithMostRecentClaimAndIndicator'
},
P8224 = {
alt = 'Изображение молекулярной модели',
},
},
categories = {
['links-to-entities-with-missing-label'] = 'Википедия:Статьи со ссылками на элементы Викиданных без подписи',
['links-to-entities-with-wikibase-error'] = 'Википедия:Страницы с ошибками скриптов, использующих Викиданные',
['links-to-entities-with-missing-local-language-label'] = 'Википедия:Статьи со ссылками на элементы Викиданных без русской подписи',
['media-contains-local-caption'] = 'Википедия:Локальная подпись у изображения из Викиданных',
['media-contains-markup'] = 'Википедия:Статьи с вики-разметкой в изображении карточки',
['media-contains-local-double'] = 'Википедия:Изображение в статье дублирует изображение в карточке',
['value-contains-table'] = 'Википедия:Статьи с табличной вставкой в карточке',
},
errors = {
['property-param-not-provided'] = 'Не дан параметр свойства',
['entity-not-found'] = 'Сущность не найдена.',
['unknown-claim-type'] = 'Неизвестный тип заявления.',
['unknown-snak-type'] = 'Неизвестный тип снэка.',
['unknown-datavalue-type'] = 'Неизвестный тип значения данных.',
['unknown-entity-type'] = 'Неизвестный тип сущности.',
['unknown-property-module'] = 'Вы должны установить и property-module, и property-function.',
['unknown-claim-module'] = 'Вы должны установить и claim-module, и claim-function.',
['unknown-value-module'] = 'Вы должны установить и value-module, и value-function.',
['property-module-not-found'] = 'Модуль для отображения свойства не найден',
['property-function-not-found'] = 'Функция для отображения свойства не найдена',
['claim-module-not-found'] = 'Модуль для отображения утверждения не найден.',
['claim-function-not-found'] = 'Функция для отображения утверждения не найдена.',
['value-module-not-found'] = 'Модуль для отображения значения не найден.',
['value-function-not-found'] = 'Функция для отображения значения не найдена.',
},
i18n = {
somevalue = "''неизвестно''",
novalue = '',
-- Обстоятельства источника
Q5727902 = 'около ',
Q18122778 = '<span style="border-bottom: 1px dotted; cursor: help;" title="предположительно">предп.</span> ',
Q30230067 = 'возможно ',
Q52834024 = '<span style="border-bottom: 1px dotted; cursor: help;" title="менее чем"><</span> ',
Q54418095 = '<span style="border-bottom: 1px dotted; cursor: help;" title="более чем">></span> ',
thousandPowers = {'', ' тыс.', ' млн', ' млрд', ' трлн'},
},
deprecatedSources = {
Q355 = true, -- Facebook
Q36578 = true, -- Gemeinsame Normdatei
Q63056 = true, -- Find a Grave
Q212256 = true, -- АиФ
Q504063 = true, -- Discogs
Q523660 = true, -- International Music Score Library Project by https://ru.wikipedia.org/?diff=107090748
Q1798125 = true, -- LIBRIS
Q2621214 = true, -- Geni
Q15222191 = true, -- BNF
Q15241312 = true, -- Freebase
Q19938912 = true, -- BNF
Q21697707 = true, -- Хайазг
Q25328680 = true, -- Prabook
Q29861311 = true, -- SNAC
Q86999151 = true, -- WeChangEd
},
};
b786cd0414ef1bee304179c30b5daff1eda5baf8
Модуль:Transclude
828
144
331
330
2024-08-10T15:21:04Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
local p={}
-- Вызывает внутренний шаблон с аргументами объемлющего шаблона
function p.call(frame)
local template = frame.args[1]
local args = frame:getParent().args
return frame:expandTemplate{ title=template, args=args }
end
-- Общая реализация для forall и call
local function forallImpl(args, separator, conjunction, func)
-- нумерованные ключи из args
local keys = {}
-- перебор в произвольном порядке, даже для нумерованных ключей
for key, value in pairs(args) do
if type(key) == 'number' and value and value ~= '' then
table.insert(keys, key)
end
end
table.sort(keys)
local results = {}
for _, key in ipairs(keys) do
local value = func(args[key])
table.insert(results, value)
end
return mw.text.listToText(results, separator, conjunction)
end
-- Вызывает внутренний шаблон, передавая ему нумерованные параметры объемлющего шаблона по-одному
function p.forall(frame)
local template = frame.args[1]
local separator = frame.args.separator or ''
local conjunction = frame.args.conjunction or separator
local args = frame:getParent().args
local func = function(value)
return frame:expandTemplate{ title = template, args = {value} } -- или другой frame?
end
return forallImpl(args, separator, conjunction, func)
end
-- Берёт нумерованные аргументы объемлющего шаблона и склеивает их в единую строку
function p.join(frame)
local separator = frame.args[1] or ''
local conjunction = frame.args[2] or separator
local args = frame:getParent().args
local func = function(value)
return value
end
return forallImpl(args, separator, conjunction, func)
end
-- Служебная функция: удаляет дубликаты из отсортированного массива с нумерованными индексами
local function deleteDuplicates(args)
local res = {}
for key, value in pairs(args) do
if args[key+1] ~= value then
table.insert(res, value)
end
end
return res
end
-- Вызывает внутренний шаблон несколько раз, передавая в него блоки аргументов объемлющего шаблона
function p.npc(frame)
local args = frame:getParent().args
local templateFrame = frame:getParent()
local template = frame.args[1]
-- определение, блоки аргументов с какими номерами нужны:
-- если в объемлющем шаблоне есть "параметр12" и в вызове модуля есть "параметр", то вызывается 12-й блок
local nums = {}
for key, _ in pairs(args) do
local main, num = string.match(key, '^(.-)%s*(%d*)$')
num = tonumber(num)
-- учитывать "параметр12", только если задано "параметр"
if num and frame.args[main] then
table.insert(nums, num)
end
end
table.sort(nums)
nums = deleteDuplicates(nums)
-- проходить по нужным номерам блоков по возрастанию и однократно
-- подставлять в шаблон:
-- 1. общие аргументы данного модуля
-- 2. аргументы объемлющего шаблона вида "параметр12" как "параметр" в 12-й блок
local results = {}
for _, blockNum in ipairs(nums) do
-- общие аргументы модуля, которые передаются в каждый блок
local blockArgs = mw.clone(frame.args)
-- metatable ломает expandTemplate
setmetatable(blockArgs, nil)
for key, value in pairs(args) do
local main, num = string.match(key, '^(.-)%s*(%d*)$')
num = tonumber(num)
-- передавать "параметр12" как "параметр" в 12-й блок, только если есть "параметр" в вызове модуля
if blockNum == num and frame.args[main] then
blockArgs[main] = value
end
end
local blockText = templateFrame:expandTemplate{ title=template; args=blockArgs }
table.insert(results, blockText)
end
return table.concat(results)
end
-- Действует аналогично forall по числовой переменной, изменяющейся (по умолчанию, от 1) до f.args[2].
function p.cycle(f)
local tf,ac,op=f:getParent(), {}, f.args.output or 'inline';
local sep='';
if op == 'newline' then
sep='\n';
end
for p,k in pairs(f.args) do
if type(p)=='number' then
if p>2 then ac[p-1]=k end
else ac[p]=k
end
end
local s,fh = f.args[2]:match('^%s*(%-?%d+)%s*%.%.') or 1,
f.args[2]:match('%.%.%s*(%S.*)%s*$') or f.args[2] or '';
fh=tonumber(fh) or fh:match('^%s*(.-)%s*$');
s=tonumber(s);
local acr={};
if not s then error('Начало цикла «'..s..'» — не число') end
local function dc(order)
local r=tf:expandTemplate{ title=f.args[1]; args={s,unpack(ac)} }
if order == 'desc' then
s=s-1;
else
s=s+1;
end
if r~='' then table.insert(acr,r); return r end
end
if type(fh)=='number' then
if fh > s then
while s<=fh do dc('asc') end
else
while s>=fh do dc('desc') end
end
elseif fh~='' then
while tf:expandTemplate{ title=fh; args={s,unpack(ac)} } do dc('asc') end
else
while dc('asc') do end
end
return table.concat(acr, sep)
end
return p
c17cfab4cebc23157f5ab8d18c7e4f5c273bfa59
Шаблон:Replace
10
145
333
332
2024-08-10T15:21:04Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{safesubst:<noinclude />#invoke:String|replace|source={{{1}}}|{{{2}}}|{{{3}}}|plain={{{plain|true}}}|count={{{count|}}}}}<noinclude>
{{doc}}
</noinclude>
7752c3c70ae8c46a89a0808aa282956866dbba5b
Шаблон:Str left
10
146
335
334
2024-08-10T15:21:04Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>padleft:|{{{2|1}}}|{{{1|}}}}}<noinclude>
{{doc}}
</noinclude>
c1f57b63826f4d455dcaec8d2c24a2b8268f42ec
Шаблон:Nobr
10
147
337
336
2024-08-10T15:21:05Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly><span class="nowrap">{{{1}}}</span></includeonly><noinclude>
{{doc}}
<!-- Пожалуйста, добавляйте категории и интервики на страницу документации! -->
</noinclude>
989c6f164ed3a8543e916c8f1746ba1ab94fb068
Шаблон:If-wikidata
10
148
339
338
2024-08-10T15:21:05Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{#switch:{{wikidata|{{{1|}}}|{{{2|}}}|plain={{{plain|true}}}|from={{{from|}}}|somevalue={{{somevalue|}}}|novalue={{{novalue|}}}}}|значение отсутствует|={{{4|}}}|#default={{{3}}}}}<noinclude>
{{doc}}
</noinclude>
a8a37fd2c4f1a266ec48783d7d0ad22cdcd812cb
Модуль:Wikidata/media
828
149
341
340
2024-08-10T15:21:06Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
local p = {}
-- Константы
local contentLanguageCode = mw.getContentLanguage():getCode();
function p.formatCommonsCategory( context, options, value )
local link = 'commons:Category:' .. value
local title = value .. ' на Викискладе'
if ( options['text'] and options['text'] ~= '' ) then
title = options['text']
end
commons = '[[' .. link .. '|' .. title .. ']]'
--Commons icon
if ( not options['icon'] or options['icon'] ~= '-' ) then
local icon_size = '15px'
if ( options['icon_size'] and options['icon_size'] ~= '' ) then
icon_size = options['icon_size']
end
commons = '[[File:Commons-logo.svg|' .. icon_size .. '|link=' .. link .. '|alt=Логотип Викисклада]] ' .. commons
end
--Text before and after link
if ( options['text_before'] and options['text_before'] ~= '' ) then
if ( options['text_before'] ~= '-' ) then
commons = options['text_before'] .. ' ' .. commons
end
end
if ( options['text_after'] and options['text_after'] ~= '' ) then
if ( options['text_after'] ~= '-' ) then
commons = commons .. ' ' .. options['text_after']
end
end
return commons
end
--[[
Временный хак, нужно добавить config, getConfig и getCategoryByCode
в options, чтобы они были доступны в любом месте кода.
]]
local config;
local function getCategoryByCode( code, sortkey )
if config == nil then
config = require( 'Module:Wikidata/config' );
end;
local value = config[ 'categories' ][ code ];
if not value or value == '' then
return '';
end
return '[[Category:' .. value .. ']]';
end
local function getCaption( context, options )
local caption = ''
if options.qualifiers and options.qualifiers.P2096 then
for i, qualifier in pairs( options.qualifiers.P2096 ) do
if ( qualifier
and qualifier.datavalue
and qualifier.datavalue.type == 'monolingualtext'
and qualifier.datavalue.value
and qualifier.datavalue.value.language == contentLanguageCode ) then
caption = qualifier.datavalue.value.text
break
end
end
end
if options['appendTimestamp'] and options.qualifiers and options.qualifiers.P585 and options.qualifiers.P585[1] then
local moment = context.formatValueDefault( context, options, options.qualifiers.P585[1].datavalue )
if not caption or caption == '' then
caption = moment
else
caption = caption .. ', ' .. moment
end
end
local localValue = '';
if options[ 'value' ] and options[ 'value' ] ~= '' then
localValue = options[ 'value' ];
end
local localCaption = '';
if options[ 'caption' ] and options[ 'caption' ] ~= '' then
localCaption = options[ 'caption' ];
end
if localValue ~= '' then
caption = localCaption;
end
local formattedCaption = ''
if caption ~= '' then
formattedCaption = context.wrapQualifier( caption, 'P2096', { class = 'media-caption', style = 'display:block' } );
end
if localValue == '' and localCaption ~= '' then
formattedCaption = formattedCaption .. getCategoryByCode( 'media-contains-local-caption' )
if options.frame:preprocess('{{REVISIONID}}') == '' then
formattedCaption = formattedCaption .. '<span class="error" style="font-size:94%;">Локальная подпись не используется, потому что изображение берётся из Викиданных, см. [[Википедия:Шаблоны-карточки#Описание изображения в Викиданных|здесь]]</span>'
end
end
return caption, formattedCaption
end
function p.formatCommonsMediaValue( context, options, value )
local image = value;
local caption, formattedCaption = getCaption( context, options )
if not string.find( value, '[%[%]%{%}]' ) and not string.find( value, 'UNIQ%-%-imagemap' ) then
-- если в value не содержится викикод или imagemap, то викифицируем имя файла
-- ищем слово imagemap в строке, потому что вставляется плейсхолдер: [[PHAB:T28213]]
image = '[[File:' .. value .. '|frameless';
if options[ 'border' ] and options[ 'border' ] ~= '' then
image = image .. '|border';
end
local size = options[ 'size' ];
if size and size ~= '' then
if not string.match( size, 'px$' )
and not string.match( size, 'пкс$' ) -- TODO: использовать перевод для языка вики
then
size = size .. 'px'
end
-- временно
if string.match( size, 'pxpx' ) then
image = '[[Категория:Википедия:Изображение с pxpx в размере]]' .. image
end
else
size = fileDefaultSize;
end
image = image .. '|' .. size;
if options[ 'alt' ] and options[ 'alt' ] ~= '' then
image = image .. '|alt=' .. options[ 'alt' ];
end
if caption ~= '' then
image = image .. '|' .. caption
end
image = image .. ']]';
if formattedCaption ~= '' then
image = image .. '<br>' .. formattedCaption;
end
else
image = image .. formattedCaption .. getCategoryByCode( 'media-contains-markup' );
end
if options.entity and options.fixdouble then
local page = mw.title.getCurrentTitle()
local txt = page:getContent()
if txt and txt:match(':' .. value) and mw.title.getCurrentTitle():inNamespace(0) then
if options.frame:preprocess('{{REVISIONID}}') == '' then
image = image .. '<span class="error">Это изображение встречается ниже по тексту статьи; пожалуйста, уберите одну из копий (не потеряв при этом подпись)</span>'
end
image = image .. getCategoryByCode( 'media-contains-local-double' )
end
end
return image
end
return p
ec384e72491465f4103cce95a8f9467df428a432
Шаблон:Join
10
150
343
342
2024-08-10T15:21:06Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>#invoke:Separated entries|main|separator={{{separator|}}}}}<noinclude>
{{doc}}
<!-- Категории — на подстраницу /doc, интервики — в Викиданные. -->
</noinclude>
92bb17b5322d3ae0ceab93d4dad3d31810d47eb0
Модуль:Color contrast
828
151
345
344
2024-08-10T15:21:07Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
--
-- This module implements
-- {{Color contrast ratio}}
-- {{Greater color contrast ratio}}
-- {{ColorToLum}}
-- {{RGBColorToLum}}
--
local p = {}
local HTMLcolor = mw.loadData( 'Module:Color contrast/colors' )
local function sRGB ( v )
if (v <= 0.03928) then
v = v / 12.92
else
v = math.pow((v+0.055)/1.055, 2.4)
end
return v
end
local function rgbdec2lum( R, G, B )
if ( 0 <= R and R < 256 and 0 <= G and G < 256 and 0 <= B and B < 256 ) then
return 0.2126 * sRGB(R/255) + 0.7152 * sRGB(G/255) + 0.0722 * sRGB(B/255)
else
return ''
end
end
local function hsl2lum( h, s, l )
if ( 0 <= h and h < 360 and 0 <= s and s <= 1 and 0 <= l and l <= 1 ) then
local c = (1 - math.abs(2*l - 1))*s
local x = c*(1 - math.abs( math.fmod(h/60, 2) - 1) )
local m = l - c/2
local r, g, b = m, m, m
if( 0 <= h and h < 60 ) then
r = r + c
g = g + x
elseif( 60 <= h and h < 120 ) then
r = r + x
g = g + c
elseif( 120 <= h and h < 180 ) then
g = g + c
b = b + x
elseif( 180 <= h and h < 240 ) then
g = g + x
b = b + c
elseif( 240 <= h and h < 300 ) then
r = r + x
b = b + c
elseif( 300 <= h and h < 360 ) then
r = r + c
b = b + x
end
return rgbdec2lum(255*r, 255*g, 255*b)
else
return ''
end
end
local function color2lum( c )
if (c == nil) then
return ''
end
-- whitespace
c = c:match( '^%s*(.-)[%s;]*$' )
-- lowercase
c = c:lower()
-- first try to look it up
local L = HTMLcolor[c]
if (L ~= nil) then
return L
end
-- convert from hsl
if mw.ustring.match(c,'^hsl%([%s]*[0-9][0-9%.]*[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*%)$') then
local h, s, l = mw.ustring.match(c,'^hsl%([%s]*([0-9][0-9%.]*)[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*%)$')
return hsl2lum(tonumber(h), tonumber(s)/100, tonumber(l)/100)
end
-- convert from rgb
if mw.ustring.match(c,'^rgb%([%s]*[0-9][0-9]*[%s]*,[%s]*[0-9][0-9]*[%s]*,[%s]*[0-9][0-9]*[%s]*%)$') then
local R, G, B = mw.ustring.match(c,'^rgb%([%s]*([0-9][0-9]*)[%s]*,[%s]*([0-9][0-9]*)[%s]*,[%s]*([0-9][0-9]*)[%s]*%)$')
return rgbdec2lum(tonumber(R), tonumber(G), tonumber(B))
end
-- convert from rgb percent
if mw.ustring.match(c,'^rgb%([%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*,[%s]*[0-9][0-9%.]*%%[%s]*%)$') then
local R, G, B = mw.ustring.match(c,'^rgb%([%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*,[%s]*([0-9][0-9%.]*)%%[%s]*%)$')
return rgbdec2lum(255*tonumber(R)/100, 255*tonumber(G)/100, 255*tonumber(B)/100)
end
-- remove leading # (if there is one) and whitespace
c = mw.ustring.match(c, '^[%s#]*([a-f0-9]*)[%s]*$')
-- split into rgb
local cs = mw.text.split(c or '', '')
if( #cs == 6 ) then
local R = 16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[2])
local G = 16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[4])
local B = 16*tonumber('0x' .. cs[5]) + tonumber('0x' .. cs[6])
return rgbdec2lum(R, G, B)
elseif ( #cs == 3 ) then
local R = 16*tonumber('0x' .. cs[1]) + tonumber('0x' .. cs[1])
local G = 16*tonumber('0x' .. cs[2]) + tonumber('0x' .. cs[2])
local B = 16*tonumber('0x' .. cs[3]) + tonumber('0x' .. cs[3])
return rgbdec2lum(R, G, B)
end
-- failure, return blank
return ''
end
function p._greatercontrast(args)
local bias = tonumber(args['bias'] or '0') or 0
local v1 = color2lum(args[1] or '')
local c2 = args[2] or '#FFFFFF'
local v2 = color2lum(c2)
local c3 = args[3] or '#000000'
local v3 = color2lum(c3)
local ratio1 = 0;
local ratio2 = 0;
if (type(v1) == 'number' and type(v2) == 'number') then
ratio1 = (v2 + 0.05)/(v1 + 0.05)
ratio1 = (ratio1 < 1) and 1/ratio1 or ratio1
end
if (type(v1) == 'number' and type(v3) == 'number') then
ratio2 = (v3 + 0.05)/(v1 + 0.05)
ratio2 = (ratio2 < 1) and 1/ratio2 or ratio2
end
return (ratio1 + bias > ratio2) and c2 or c3
end
function p._ratio(args)
local v1 = color2lum(mw.text.unstripNoWiki(args[1] or ''))
local v2 = color2lum(mw.text.unstripNoWiki(args[2] or ''))
if (type(v1) == 'number' and type(v2) == 'number') then
-- v1 should be the brighter of the two.
if v2 > v1 then
v1, v2 = v2, v1
end
return (v1 + 0.05)/(v2 + 0.05)
else
return args['error'] or '?'
end
end
function p._styleratio(args)
local style = (args[1] or ''):lower()
local bg, fg = 'white', '#202122'
local lum_bg, lum_fg = 1, 0.016
if args[2] then
local lum = color2lum(args[2])
if lum ~= '' then bg, lum_bg = args[2], lum end
end
if args[3] then
local lum = color2lum(args[3])
if lum ~= '' then fg, lum_fg = args[3], lum end
end
local slist = mw.text.split(style or '', ';')
for k = 1, #slist do
local s = slist[k]
local k, v = s:match( '^[%s]*([^:]-):([^:]-)[%s;]*$' )
k = k or ''
v = v or ''
if (k:match('^[%s]*(background)[%s]*$') or k:match('^[%s]*(background%-color)[%s]*$')) then
local lum = color2lum(v)
if( lum ~= '' ) then bg, lum_bg = v, lum end
elseif (k:match('^[%s]*(color)[%s]*$')) then
local lum = color2lum(v)
if( lum ~= '' ) then bg, lum_fg = v, lum end
end
end
if lum_bg > lum_fg then
return (lum_bg + 0.05)/(lum_fg + 0.05)
else
return (lum_fg + 0.05)/(lum_bg + 0.05)
end
end
function p.lum(frame)
return color2lum(frame.args[1] or frame:getParent().args[1])
end
function p.ratio(frame)
local args = frame.args[1] and frame.args or frame:getParent().args
return p._ratio(args)
end
function p.styleratio(frame)
local args = frame.args[1] and frame.args or frame:getParent().args
return p._styleratio(args)
end
function p.greatercontrast(frame)
local args = frame.args[1] and frame.args or frame:getParent().args
return p._greatercontrast(args)
end
return p
cce580326bee8eaf3c81df6c76c04a9a2909dfa2
Модуль:Color contrast/colors
828
152
347
346
2024-08-10T15:21:07Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
return {
aliceblue = 0.92880068253475,
antiquewhite = 0.84646951707754,
aqua = 0.7874,
aquamarine = 0.8078549208338,
azure = 0.97265264954166,
beige = 0.8988459998705,
bisque = 0.80732327372979,
black = 0,
blanchedalmond = 0.85084439608156,
blue = 0.0722,
blueviolet = 0.12622014321946,
brown = 0.098224287876511,
burlywood = 0.51559844533893,
cadetblue = 0.29424681085422,
chartreuse = 0.76032025902623,
chocolate = 0.23898526114557,
coral = 0.37017930872924,
cornflowerblue = 0.30318641994179,
cornsilk = 0.93562110372965,
crimson = 0.16042199953026,
cyan = 0.7874,
darkblue = 0.018640801980939,
darkcyan = 0.20329317839046,
darkgoldenrod = 0.27264703559993,
darkgray = 0.39675523072563,
darkgreen = 0.091143429047575,
darkgrey = 0.39675523072563,
darkkhaki = 0.45747326349994,
darkmagenta = 0.07353047651207,
darkolivegreen = 0.12651920884889,
darkorange = 0.40016167026524,
darkorchid = 0.13413142174857,
darkred = 0.054889674531132,
darksalmon = 0.40541471563381,
darkseagreen = 0.43789249325969,
darkslateblue = 0.065792846227988,
darkslategray = 0.067608151928044,
darkslategrey = 0.067608151928044,
darkturquoise = 0.4874606277449,
darkviolet = 0.10999048339343,
deeppink = 0.23866895828276,
deepskyblue = 0.44481603395575,
dimgray = 0.14126329114027,
dimgrey = 0.14126329114027,
dodgerblue = 0.27442536991456,
firebrick = 0.10724525535015,
floralwhite = 0.95922484825004,
forestgreen = 0.18920812076002,
fuchsia = 0.2848,
gainsboro = 0.71569350050648,
ghostwhite = 0.94311261886323,
gold = 0.69860877428159,
goldenrod = 0.41919977809569,
gray = 0.2158605001139,
green = 0.15438342968146,
greenyellow = 0.80609472611453,
grey = 0.2158605001139,
honeydew = 0.96336535554782,
hotpink = 0.34658438169715,
indianred = 0.21406134963884,
indigo = 0.03107561486337,
ivory = 0.99071270600615,
khaki = 0.77012343394121,
lavender = 0.80318750514521,
lavenderblush = 0.90172748631046,
lawngreen = 0.73905893124963,
lemonchiffon = 0.94038992245622,
lightblue = 0.63709141280807,
lightcoral = 0.35522120733135,
lightcyan = 0.94587293494829,
lightgoldenrodyellow = 0.93348351018297,
lightgray = 0.65140563741982,
lightgreen = 0.69091979956865,
lightgrey = 0.65140563741982,
lightpink = 0.58566152734898,
lightsalmon = 0.4780675225206,
lightseagreen = 0.35050145117042,
lightskyblue = 0.56195637618331,
lightslategray = 0.23830165007287,
lightslategrey = 0.23830165007287,
lightsteelblue = 0.53983888284666,
lightyellow = 0.98161818392882,
lime = 0.7152,
limegreen = 0.44571042246098,
linen = 0.88357340984379,
magenta = 0.2848,
maroon = 0.045891942324215,
mediumaquamarine = 0.49389703310801,
mediumblue = 0.044077780212328,
mediumorchid = 0.21639251153773,
mediumpurple = 0.22905858091648,
mediumseagreen = 0.34393112338131,
mediumslateblue = 0.20284629471622,
mediumspringgreen = 0.70704308194184,
mediumturquoise = 0.5133827926448,
mediumvioletred = 0.14371899849357,
midnightblue = 0.02071786635086,
mintcream = 0.97834604947588,
mistyrose = 0.82183047859185,
moccasin = 0.80083000991567,
navajowhite = 0.76519682342785,
navy = 0.015585128108224,
oldlace = 0.91900633405549,
olive = 0.20027537200568,
olivedrab = 0.22593150951929,
orange = 0.4817026703631,
orangered = 0.25516243753416,
orchid = 0.31348806761439,
palegoldenrod = 0.78792647887614,
palegreen = 0.77936759006353,
paleturquoise = 0.76436077921714,
palevioletred = 0.28754994117889,
papayawhip = 0.87797100199835,
peachpuff = 0.74905589878251,
peru = 0.30113074877936,
pink = 0.63271070702466,
plum = 0.45734221587969,
powderblue = 0.68254586500605,
purple = 0.061477070432439,
rebeccapurple = 0.07492341159447,
red = 0.2126,
rosybrown = 0.32319457649407,
royalblue = 0.16663210743188,
saddlebrown = 0.097922285020521,
salmon = 0.36977241527596,
sandybrown = 0.46628543696283,
seagreen = 0.19734199706275,
seashell = 0.92737862206922,
sienna = 0.13697631337098,
silver = 0.52711512570581,
skyblue = 0.55291668518184,
slateblue = 0.14784278062136,
slategray = 0.20896704076536,
slategrey = 0.20896704076536,
snow = 0.96533341834849,
springgreen = 0.73052306068529,
steelblue = 0.20562642207625,
tan = 0.48237604163921,
teal = 0.16996855778968,
thistle = 0.56818401093733,
tomato = 0.30638612719415,
turquoise = 0.5895536427578,
violet = 0.40315452986676,
wheat = 0.74909702820482,
white = 1,
whitesmoke = 0.91309865179342,
yellow = 0.9278,
yellowgreen = 0.50762957208707,
}
6ae47fdb24de4eed5ec26d203faf5341a388987b
Шаблон:Yesno-yes
10
153
349
348
2024-08-10T15:21:07Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{safesubst:<noinclude />yesno|{{{1}}}|yes={{{yes|yes}}}|no={{{no|no}}}|blank={{{blank|yes}}}|¬={{{¬|yes}}}|def={{{def|yes}}}}}<noinclude>
{{doc}}
</noinclude>
3792ff694708f98102e3a6d556abe73bedc29069
Шаблон:Карточка/оригинал названия
10
154
351
350
2024-08-10T15:21:08Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{wikidata|p1705[language!:ru]|{{{1|}}}|separator=<br>|conjunction=<br>|monolingualLangTemplate=lang|from={{{from|}}}}}<!--
-->{{#if:{{NAMESPACE}}||{{#if:{{{1|}}}|{{#ifeq:{{#invoke:String|find|{{{1|}}}|span}}|0|[[Категория:Википедия:Статьи с оригиналом названия без шаблона lang-XX]]}}}}}}<noinclude>{{doc}}</noinclude>
4eccda042428e1113ff320ff5d6b760a7f52b088
Шаблон:Br separated entries
10
155
353
352
2024-08-10T15:21:08Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>#invoke:Separated entries|br}}<noinclude>
{{doc}}
</noinclude>
2113c3c6e95a84235b9f7a85e7ea17208e8f91df
Шаблон:Карточка/блок с маркерами
10
156
355
354
2024-08-10T15:21:09Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{#invoke:Infobox/bulleted block|main}}<noinclude>{{doc}}</noinclude>
71e7755aa4fb1e445f008da13d6fa4212aea3c38
Шаблон:Карточка/блок
10
157
357
356
2024-08-10T15:21:10Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{#invoke:Infobox|renderLines}}</includeonly><noinclude>{{doc}}</noinclude>
b76f4bc95a8a44fea1fa0f577d84111b51ce1385
Модуль:Separated entries
828
158
359
358
2024-08-10T15:21:10Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
-- This module takes positional parameters as input and concatenates them with
-- an optional separator. The final separator (the "conjunction") can be
-- specified independently, enabling natural-language lists like
-- "foo, bar, baz and qux".
local compressSparseArray = require('Module:TableTools').compressSparseArray
local p = {}
function p._main(args)
local separator = args.separator
-- Decode (convert to Unicode) HTML escape sequences, such as " " for space.
and mw.text.decode(args.separator) or ''
local conjunction = args.conjunction and mw.text.decode(args.conjunction) or separator
-- Discard named parameters.
local values = compressSparseArray(args)
return mw.text.listToText(values, separator, conjunction)
end
local function makeInvokeFunction(separator, conjunction)
return function (frame)
local args = require('Module:Arguments').getArgs(frame)
args.separator = separator or args.separator
args.conjunction = conjunction or args.conjunction
return p._main(args)
end
end
p.main = makeInvokeFunction()
p.br = makeInvokeFunction('<br />')
p.newline = makeInvokeFunction('\n')
p.comma = makeInvokeFunction(mw.message.new('comma-separator'):plain())
return p
33a68f0a46d62c42b6523a548f0f881e82ecfe58
Модуль:Infobox/bulleted block
828
159
361
360
2024-08-10T15:21:10Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
local p = {}
-- takes strings or nils; returns a string
function makeText(frame, text, wikidata, from)
if wikidata and wikidata ~= ''then
return frame:expandTemplate{title='Wikidata', args={wikidata, text or '', from=from or ''}}
else
return text or ''
end
end
-- from [[ru:Модуль:Infobox]]
local function maxNumber ( args )
local maxNumber = 0
for argName, _ in pairs(args) do
local argNumber = mw.ustring.match(argName, '^[^0-9]+([0-9]+)$')
if argNumber and tonumber(argNumber) > maxNumber then
maxNumber = tonumber(argNumber)
end
end
return maxNumber
end
function p.main(frame)
local args = frame:getParent().args
local maxNumberArgs = maxNumber(args)
local texts = {}
for i = 1, maxNumberArgs do
if args['текст' .. i] then
texts[i] = makeText(frame, args['текст' .. i], args['викиданные' .. i], args['from'])
end
end
local textsAreEmpty = true
for i = 1, maxNumberArgs do
if texts[i] and texts[i] ~= '' then
textsAreEmpty = false
end
end
local results = {}
if not textsAreEmpty and args['подзаголовок'] and args['подзаголовок'] ~= '' then
results['текст1'] = args['подзаголовок']
results['стиль_текста1'] = 'padding-bottom:0; border-bottom:0; text-align:left; font-weight:bold;'
end
local mainText = makeText(frame, args['текст'], args['викиданные'], args['from'])
if mainText == '' and args['метка'] and args['метка'] ~= '' and not textsAreEmpty then
mainText = ' '
end
if mainText and mainText ~= '' then
results['метка2'] = args['метка']
results['стиль_метки2'] = 'padding-bottom:0; border-bottom:0;'
results['текст2'] = mainText
results['стиль_текста2'] = 'padding-bottom:0; border-bottom:0;'
end
for i = 1, maxNumberArgs do
if texts[i] and texts[i] ~= '' then
results['метка' .. (i+2)] = ' • ' .. (args['метка' .. i] or '')
results['текст' .. (i+2)] = texts[i]
local last = true
for j = i+1, maxNumberArgs do
if texts[j] and texts[j] ~= '' then
last = false
end
end
if last then
results['стиль_метки' .. (i+2)] = 'font-weight:normal; padding-top:0; border-top:0;'
results['стиль_текста' .. (i+2)] = 'padding-top:0; border-top:0;'
else
results['стиль_метки' .. (i+2)] = 'font-weight:normal; padding-bottom:0; border-bottom:0; padding-top:0; border-top:0;'
results['стиль_текста' .. (i+2)] = 'padding-bottom:0; border-bottom:0; padding-top:0; border-top:0;'
end
end
end
return frame:expandTemplate{title='Карточка/блок', args=results}
end
return p
856b97606e1f2809c940e384f6fe71a575ca019e
Шаблон:Число
10
160
363
362
2024-08-10T15:21:11Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{formatnum: {{replace|{{{1}}}|,|.}} }}{{#if: {{{1|}}} | {{#if: {{{2|}}} | {{nobr|1= {{{2|}}}}} }} }}<noinclude>
{{doc}}
</noinclude>
acfc1e9cec817e6742b18106f020ac388ececc7e
Шаблон:T
10
161
365
364
2024-08-10T15:21:11Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
#перенаправление [[Шаблон:Tl]]
c0a76efe437d8a513d9f6878297f399a23944abd
Шаблон:Tl
10
162
367
366
2024-08-10T15:21:12Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{{{{|safesubst:}}}#invoke: Template call code | withoutParams }}<noinclude>{{doc}}</noinclude>
61fe4d068895a5e7e5802767f5d7df71a7561c57
Модуль:Wikidata/count
828
163
369
368
2024-08-10T15:21:12Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
local p = {}
function p.getCount( context, options )
if ( not context ) then error( 'context not specified' ); end;
if ( not options ) then error( 'options not specified' ); end;
if ( not options.entity ) then error( 'options.entity missing' ); end;
local claims;
if options.property then -- TODO: Почему тут может не быть property?
claims = context.selectClaims( options, options.property );
end
if claims == nil then
return ''; --TODO error?
end
return table.getn(claims);
end
function p.isMultiple( context, options )
local count = p.getCount( context, options );
local multiple = '';
if( count ~= nil and count ~= '' and count > 1 ) then
multiple = 1;
end
return multiple;
end
return p
8ccf5dd7170a466674627b0afdf32c6bd2318154
Шаблон:Str sub
10
164
371
370
2024-08-10T15:21:13Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{{{{|safesubst:}}}#invoke:String|sublength|s={{{1}}}|i={{{2|0}}}|len={{{3|0}}}}}</includeonly><noinclude>
{{doc}}
</noinclude>
3043790f8803e868cf6097b475fd58ba742887fe
Шаблон:Без начала
10
165
373
372
2024-08-10T15:21:13Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>#ifeq:{{<includeonly>safesubst:</includeonly>Str_left|{{{1}}}|{{<includeonly>safesubst:</includeonly>#expr:{{<includeonly>safesubst:</includeonly>str len|{{{2}}}*}}-1}}}}*|{{{2}}}*|{{<includeonly>safesubst:</includeonly>Str_right|{{{1}}}|{{<includeonly>safesubst:</includeonly>#expr:{{<includeonly>safesubst:</includeonly>str len|{{{2}}}*}}-1}}}}|{{{1}}}}}<noinclude>{{doc}}</noinclude>
9fbca6f1fc236cb17fe77d76891e3f9c2afa2117
Шаблон:Str len
10
166
375
374
2024-08-10T15:21:14Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{{{{|safesubst:}}}#invoke:String|len|s={{{1|}}}}}<noinclude>
{{doc}}
<!-- Add categories and interwikis to the /doc subpage, not here! -->
</noinclude>
95f10258d5214440d2706952656564f216c2e4cc
Шаблон:Str rightc
10
167
377
376
2024-08-10T15:21:15Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>Str sub|{{{1}}}|{{<includeonly>safesubst:</includeonly>#expr:{{<includeonly>safesubst:</includeonly>Str len|{{{1}}}}}-{{{2}}}}}|{{{2}}}}}<noinclude>{{doc}}</noinclude>
0401d500dcc2224d44867ba0ea1f6c0fbeb758a0
Модуль:Hash
828
168
379
378
2024-08-10T15:21:15Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
local getArgs = require('Module:Arguments').getArgs
local p = {}
local function inTable(table, value)
for k, v in pairs(table) do
if v == value then
return true
end
end
return false
end
function p.list(frame)
return table.concat(mw.hash.listAlgorithms(), '; ')
end
function p.main(frame)
local args = getArgs(frame, { frameOnly = true })
local algorithm
if not args[1] then
return '<span class="error">Не указана строка для хеширования.</span>'
end
if args[2] then
if not inTable(mw.hash.listAlgorithms(), args[2]) then
return '<span class="error">Алгоритм хеширования ' .. args[2] .. ' не поддерживается, или вы неточно указали его имя. Используйте функцию <kbd>mw.hash.listAlgorithms()</kbd> для получения списка доступных алгоритмов.</span>'
end
algorithm = args[2]
else
-- Алгоритм выбран из соображений быстродействия (см. [[:en:Fowler–Noll–Vo hash function]]),
-- 64-битная функция используется для уменьшения вероятности коллизий до пренебрежимо малой
-- величины. Возможно, есть лучшая опция — проверяйте.
algorithm = 'fnv164'
end
return mw.hash.hashValue(algorithm, args[1])
end
return p
5d18513e574435f191164695449a620b031f93ec
Шаблон:Карточка/официальное название
10
169
381
380
2024-08-10T15:21:15Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{wikidata|p1448[language!:ru]|{{{1|}}}|separator=<br>|conjunction=<br>|monolingualLangTemplate=lang|from={{{from|}}}}}<noinclude>{{doc}}</noinclude>
708a700c58a199343531d8fb3eec7ee897e92732
Шаблон:Карточка/флаг и герб
10
170
383
382
2024-08-10T15:21:16Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{#if:{{if-wikidata|p41|{{{флаг|}}}|1|from={{{from|}}}}}{{if-wikidata|p94|{{{герб|}}}|1|from={{{from|}}}}}|<table role="presentation" style="background:inherit; border-collapse:collapse; width:100%; display:table; text-align:center;">
<tr>
{{if-wikidata|p41|{{{флаг|}}}|<td style<nowiki>=</nowiki>"vertical-align: middle">{{wikidata|p41|{{{флаг|}}}|from={{{from|}}}|border=true|size={{#if:{{{флаг ширина|}}}|{{{флаг ширина|}}}|160x160px}}|alt={{#if:{{{флаг подпись|}}} | {{{флаг подпись}}} | Флаг }} }}</td>}}
{{if-wikidata|p94|{{{герб|}}}|<td style<nowiki>=</nowiki>"vertical-align: middle">{{wikidata|p94|{{{герб|}}}|from={{{from|}}}|size={{#if:{{{герб ширина|}}}|{{{герб ширина|}}}|90x160px}}|alt={{#if:{{{герб подпись|}}} | {{{герб подпись}}} | Герб }} }}</td>}}
</tr>
{{#if:{{if-wikidata|p41|{{{флаг|}}}|1|from={{{from|}}}}}{{if-wikidata|p94|{{{герб|}}}|1|from={{{from|}}}}}|<tr>
{{if-wikidata|p41|{{{флаг|}}}|<td>{{#if:{{{флаг подпись|}}} | {{{флаг подпись}}} | Флаг }}</td>}}
{{if-wikidata|p94|{{{герб|}}}|<td>{{#if:{{{герб подпись|}}} | {{{герб подпись}}} | Герб }}</td>}}
</tr>}}</table>
}}<noinclude>{{doc}}</noinclude>
6d024d548f061491090c2a71067f26911973a9fd
Шаблон:Doc
10
171
385
384
2024-08-10T15:21:16Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{doc/begin|{{SUBJECTSPACE}}:{{PAGENAME:{{{1|{{SUBJECTPAGENAME}}/doc}}}}}}}
{{#if: {{{1|}}}
| {{#ifexist: {{{1}}}
| {{{{{1}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}|{{{5|}}}}}
| {{#ifexist: {{SUBJECTSPACE}}:{{{1}}}
| {{{{{1}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}|{{{5|}}}}}
| {{Документировать|{{{1}}}}}
}}
}}
| {{#ifexist: {{SUBJECTPAGENAME}}/doc
| {{{{SUBJECTPAGENAME}}/doc}}
| {{Документировать|{{SUBJECTPAGENAME}}/doc}}
}}
}}
{{doc/end}}</includeonly><noinclude>
{{doc}}
</noinclude>
391c7f0f075319e6b3305557c55e98c581696c71
Шаблон:Doc/begin
10
172
387
386
2024-08-10T15:21:16Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly><templatestyles src="Шаблон:Doc/styles.css" />
<div class="ts-doc-doc" id="doc">
<div class="ts-doc-header" id="Документация">
<div class="ts-doc-heading">Документация</div>
{{#if: {{{inline|}}} || {{Действия для страницы|lc={{{1}}}|nowatch=yes}} }}
</div>
<div class="ts-doc-content"></includeonly><noinclude>
{{doc}}
</noinclude>
c753f0a9f65d86707cdffaf93fb49c2c52daf92b
Шаблон:Doc/styles.css
10
173
389
388
2024-08-10T15:21:18Z
DuOfOrl
5
1 версия импортирована
sanitized-css
text/css
.ts-doc-doc {
background-color: var(--background-color-progressive-subtle, #eaf3ff);
border: 1px solid var(--border-color-content-added, #afb6e9);
clear: both;
margin-top: 1em;
}
/* Ctrl+F ":target" in [[MediaWiki:Common.css]] */
.ts-doc-doc sup.reference:target,
.ts-doc-doc ol.references li:target,
.ts-doc-doc .highlight-target:target,
.ts-doc-doc cite:target,
.ts-doc-doc span.citation:target {
background: var(--ruwiki-background-color-blue200, #cfe3ff);
}
.ts-doc-header {
align-items: center;
background: var(--ruwiki-background-color-blue200, #cfe3ff);
display: flex;
flex-wrap: wrap;
padding: .642857em 1em .5em;
overflow: hidden;
}
.ts-doc-header .ts-tlinks-tlinks {
margin-left: auto;
}
.ts-doc-content {
padding: .214286em 1em;
}
.ts-doc-content:after {
content: '';
clear: both;
display: block;
}
.ts-doc-heading {
display: inline-block;
padding-left: 2em;
background: url(//upload.wikimedia.org/wikipedia/commons/c/ca/OOjs_UI_icon_info.svg) center left no-repeat;
background-size: contain;
font-size: small;
min-height: 1.75em;
font-weight: 600;
letter-spacing: 0.1em;
text-transform: uppercase;
}
@media screen {
html.skin-theme-clientpref-night .ts-doc-heading {
background-image: url(//upload.wikimedia.org/wikipedia/commons/c/c0/OOjs_UI_icon_info-invert.svg);
}
}
@media screen and (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os .ts-doc-heading {
background-image: url(//upload.wikimedia.org/wikipedia/commons/c/c0/OOjs_UI_icon_info-invert.svg);
}
}
.ts-doc-content > *:first-child,
.ts-doc-footer > *:first-child {
margin-top: .5em;
}
.ts-doc-content > *:last-child,
.ts-doc-footer > *:last-child {
margin-bottom: .5em;
}
.ts-doc-footer {
background-color: var(--background-color-progressive-subtle, #eaf3ff);
border: 1px solid var(--border-color-content-added, #afb6e9);
padding: .214286em 1em;
margin-top: .214286em;
margin-bottom: .214286em;
font-style: italic;
}
@media (max-width: 719px) {
.ts-doc-header {
display: block;
}
.ts-doc-header .ts-tlinks-tlinks {
float: none;
}
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
be8d912472a37a6051bee114da86f913839e7ca0
Шаблон:Действия для страницы
10
174
391
390
2024-08-10T15:21:18Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<templatestyles src="Шаблон:Действия для страницы/styles.css" /><div style="{{#ifeq: {{yesno-yes|{{{right|}}}}} | yes || float:none; }}" class="ts-tlinks-tlinks mw-editsection-like plainlinks"><span class="mw-editsection-bracket">[</span><!--
-->{{join|separator=<span class="mw-editsection-divider"> &#124; </span>
|1={{#ifexist: {{#rel2abs: {{{lc|}}} }}
| {{#ifeq: {{{dislooklink|{{{noview|}}}}}} | yes || [[{{{lc}}}|просмотр]] }}
}}
|2={{#ifexist: {{#rel2abs: {{{lc|}}} }}
| [[Special:EditPage/{{#rel2abs: {{{lc}}} }}|править]]
}}
|3={{#ifexist: {{#rel2abs: {{{lc|}}} }}
| {{#ifeq: {{{dishistlink|{{{nohistory|}}}}}} | yes || [[Special:PageHistory/{{#rel2abs: {{{lc}}} }}|история]] }}
}}
|4={{#ifexist: {{#rel2abs: {{{lc|}}} }}
|
| [{{fullurl:{{#rel2abs: {{{lc}}} }}|action=edit&redlink=1}} создать]
}}
|5={{#ifeq: {{{diswatchlink|{{{nowatch|}}}}}} | yes || [{{fullurl:{{#rel2abs: {{{lc}}} }}|action=watch}} следить] }}
|6={{#ifeq: {{{disupdlink|{{{noupdate|}}}}}} | yes || {{очистить кэш|обновить|nocat=1}}</span> }}
}}<span class="mw-editsection-bracket">]</span></div><noinclude>
{{doc}}
</noinclude>
9ee2c9eed92e2ecc9377a7b9486ad8bc214a83d4
Шаблон:Действия для страницы/styles.css
10
175
393
392
2024-08-10T15:21:19Z
DuOfOrl
5
1 версия импортирована
sanitized-css
text/css
.ts-tlinks-tlinks {
font-weight: normal;
float: right;
line-height: inherit;
}
.ts-tlinks-tlinks .mw-editsection-divider {
display: inline;
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
a003e896d263c29e66d2246b210e5d73e577ea46
Шаблон:Doc/end
10
176
395
394
2024-08-10T15:21:19Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly></div>
</div><templatestyles src="Шаблон:Doc/styles.css" />{{#ifexpr: {{NAMESPACENUMBER}} mod 2 = 1 <!-- Например, [[Обсуждение MediaWiki:Robots.txt]] -->
| {{^|1em}}
| <div class="ts-doc-footer plainlinks">
{{#ifeq: {{str left|{{PAGENAME}}|9}}
| Песочница
|
| {{#ifeq: {{str rightc|{{PAGENAME}}|10}}
| /песочница
|
| Во избежание поломок страниц, использующих этот {{#ifeq: {{NAMESPACE}}
| Модуль
| модуль
| шаблон
}}, экспериментируйте в [[Википедия:Правка и тестирование шаблонов в песочнице|песочнице]] <small style="font-style:normal;">({{#ifexist: {{FULLPAGENAME}}/песочница
| [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit}} редактировать] {{!}} [{{fullurl:Special:ComparePages|page1={{FULLPAGENAMEE}}&page2={{FULLPAGENAMEE}}/песочница}} разница] {{#ifexist: {{FULLPAGENAME}}/тесты | {{!}} [[{{FULLPAGENAME}}/тесты|тесты]] }}
| {{#ifeq: {{NAMESPACE}} | Модуль | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit}} создать] | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit&preload=Шаблон:Doc/предзагрузка-песочница}} создать] {{!}} [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit&preload=Шаблон:Doc/зеркало}} зеркало] }}
}})</small> или {{#ifeq: {{NAMESPACE}}
| Модуль
| [[Модуль:Песочница|песочнице для модулей]]
| своём [[ВП:ЛП|личном пространстве]]
}}.<br>
}}
}}{{#ifexist: {{FULLPAGENAME}}/doc | Пожалуйста, добавляйте категории на подстраницу [[/doc]]. }}[[Special:PrefixIndex/{{FULLPAGENAME}}/|Подстраницы этого {{#ifeq: {{NAMESPACE}}
| Модуль
| модуля
| шаблона
}}]].
</div>
}}</includeonly><noinclude>{{doc}}</noinclude>
758a01a3d76e14ef14b2b0ee047ac47ddac8fd8e
Шаблон:Lang-sv
10
177
397
396
2024-08-10T15:21:20Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
[[шведский язык|швед.]] {{langi|sv|{{{1}}}}}<noinclude>{{doc|Lang/doc}}
</noinclude>
c4b5e81c6405972dcea4cc26ab77e99e9bd2021f
Шаблон:Docpage
10
178
399
398
2024-08-10T15:21:20Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{#ifeq: {{SUBPAGENAME}} | doc
| {{fmbox
| class = hlist nowraplinks
| style = margin-bottom:1em; background:var(--background-color-progressive-subtle, #eaf3ff); color:inherit; border:1px solid var(--border-color-content-added, #a3d3ff);
| image = [[Файл:OOjs UI icon info.svg|24px|link=|alt=|class=skin-invert-image]]
| text = <div>
* [[:{{#titleparts: {{SUBJECTPAGENAME}} | -1 }}]]
* [[:{{SUBJECTPAGENAME}}|Документация]]
* [[{{#titleparts: {{TALKPAGENAME}} | -1 }}|Обсуждение]]
* [[Служебная:Whatlinkshere/{{#titleparts: {{SUBJECTPAGENAME}} | -1 }}|Где используется]] {{#ifeq: {{NAMESPACE}} | {{ns:Template}} |
** {{Параметры шаблона|{{#titleparts: {{PAGENAME}} | -1 }}}}
}}</div><!--
-->{{#if: {{{nocat|}}} || {{#ifexist: {{NAMESPACE}}:{{BASEPAGENAME}} || [[Категория:Шаблоны:Документация несуществующих шаблонов]] }} }}
}}{{#if: {{{nocat|}}} || {{#ifeq: {{NAMESPACE}}
| Модуль
| [[Категория:Модули:Документация]]
| [[Категория:Шаблоны:Документация]]
}}
}}
}}</includeonly><noinclude>{{doc}}</noinclude>
9b09d5b771c19e45bd038d248dcf31e500e436ce
Шаблон:Очистить кэш
10
179
401
400
2024-08-10T15:21:21Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<!-- Класс purgelink и атрибут data-pagename используются в [[MediaWiki:Common.js]], чтобы очищать кэш без перехода на отдельную страницу --><span class="noprint purgelink" {{#if: {{{2|}}} | data-pagename="{{{2}}}" }}>{{выполнить скрипт|purgeLink}}[[Special:Purge/{{#if: {{{2|}}} | {{{2}}} | {{FULLPAGENAME}} }}|{{#if: {{{1|}}} | {{{1}}} | Очистить кэш }}]]</span>{{#ifeq: {{NAMESPACE}}{{{nocat|}}}
| {{ns:10}} <!-- Шаблон -->
| {{очищать кэш|ежедневно}}
}}<noinclude>{{doc}}</noinclude>
be6695060ca61d2125386d02d3a19109c0e7c27b
Шаблон:Население государства
10
180
403
402
2024-08-10T15:21:22Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{#switch: {{{1}}}
| Республика Южная Осетия = Население Южной Осетии{{!}}Население
| Население
}}</includeonly><noinclude>
{{doc}}
[[Категория:Шаблоны по странам]]
</noinclude>
e0568280ef5056e94f5f1abf1934f4188a52c35f
Шаблон:Lang-fi
10
181
405
404
2024-08-10T15:21:22Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
[[финский язык|фин.]] {{langi|fi|{{{1}}}}}<noinclude>{{doc|Lang/doc}}
</noinclude>
16ac91b8e1e294e7687d57c0757c178f9662581c
Шаблон:Выполнить скрипт
10
182
407
406
2024-08-10T15:21:23Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{#switch: {{{1|}}}
| =
| mainPage = [[Категория:Википедия:Заглавная страница|{{NAMESPACENUMBER}}]]
| #default = {{#ifexist: Категория:Википедия:Страницы с гаджетом по требованию {{{1}}} | [[Категория:Википедия:Страницы с гаджетом по требованию {{{1}}}|{{NAMESPACENUMBER}}]] }}
}}<noinclude>
{{doc}}
</noinclude>
6979ea0342067dc76b9adcb9a5e072207c2c5a63
Модуль:Demo
828
183
409
408
2024-08-10T15:21:24Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
local p = {}
local getArgs = require('Модуль:Arguments').getArgs
local function hasValue(param)
if param and param:find('%S') then
return true
end
end
--creates a frame object that cannot access any of the parent's args
--unless a table containing a list keys of not to inherit is provided
function disinherit(frame, onlyTheseKeys)
local parent = frame:getParent() or frame
local orphan = parent:newChild{}
orphan.getParent = parent.getParent --returns nil
orphan.args = {}
if onlyTheseKeys then
local family = {parent, frame}
for f = 1, 2 do
for k, v in pairs(family[f] and family[f].args or {}) do
orphan.args[k] = orphan.args[k] or v
end
end
parent.args = mw.clone(orphan.args)
setmetatable(orphan.args, nil)
for _, k in ipairs(onlyTheseKeys) do
rawset(orphan.args, k, nil)
end
end
return orphan, parent
end
function p.get(frame, arg, passArgs)
local orphan, frame = disinherit(frame, passArgs and {arg or 1})
local code, noWiki, preserve = frame.args[arg or 1] or ''
local kill_categories = not frame.args.save_categories
local tag, sep
if code:match'nowiki' then
local placeholder, preserve = ('6'):char(), {}
-- We replace "}%-" and "%-{" because of some server bug probably connected to
-- [[mw:Parsoid/MediaWiki DOM spec/Language conversion blocks]] and leading to
-- =mw.text.unstripNoWiki(mw.getCurrentFrame():preprocess('<nowiki>}-</nowiki>'))
-- outputting '}-' instead of "}-", while it's ok with "<nowiki>} -</nowiki>"
code = mw.text.unstripNoWiki(code)
:gsub('<', '<')
:gsub('>', '>')
:gsub('}%-', '}-')
:gsub('%-{', '-{')
if (mw.text.trim(code):match'\n') then
tag = 'pre'
sep = ''
end
noWiki = code:gsub('%%', placeholder)
for k in noWiki:gmatch('&.-;') do
table.insert(preserve, (k:gsub('&', '&')))
noWiki = noWiki:gsub('(&.-;)', '%%%s')
end
noWiki = mw.text.nowiki(noWiki):format(unpack(preserve)):gsub(placeholder, '%%')
end
return {
source = noWiki or code,
output = orphan:preprocess(code)
:gsub(kill_categories and '%[%[Категория:.-%]%]' or '', '')
:gsub(kill_categories and '%[%[К:.-%]%]' or '', '')
:gsub(kill_categories and '%[%[Category:.-%]%]' or '', ''),
frame = frame,
args = getArgs(frame),
tag = tag,
sep = sep
}
end
function p.main(frame, demoTable)
local show = demoTable or p.get(frame)
local args = show.args
local yesno = require('Module:Yesno')
args.reverse = yesno(args.reverse, false)
args.tag = hasValue(args.tag) and args.tag or hasValue(show.tag) and show.tag or "code"
args.sep = args.sep or args.br or show.sep
args.sep = tonumber(args.sep) and ('<br>'):rep(args.sep or 0) or args.sep or (args.tag == 'pre' and '' or ' → ')
if show[args.result_arg] then
return show[args.result_arg]
end
return args.reverse
and string.format(
'%s%s<%s%s%s>%s</%s>',
show.output,
args.sep,
args.tag,
hasValue(args.class) and string.format(' class="%s"', args.class) or '',
hasValue(args.style) and string.format(' style="%s"', args.style) or '',
show.source,
args.tag
)
or string.format(
'<%s%s%s>%s</%s>%s%s',
args.tag,
hasValue(args.class) and string.format(' class="%s"', args.class) or '',
hasValue(args.style) and string.format(' style="%s"', args.style) or '',
show.source,
args.tag,
args.sep,
show.output
)
end
--passing of args into other module without preprocessing
function p.module(frame)
local orphan, frame = disinherit(frame, {
'demo_template',
'demo_module',
'demo_module_func',
'demo_main',
'demo_br',
'demo_result_arg',
'demo_save_categories'
})
local template = frame.args.demo_template and 'Template:'..frame.args.demo_template
local demoFunc = frame.args.demo_module_func or 'main\n'
local demoModule = require('Module:' .. frame.args.demo_module)[demoFunc:match('^%s*(.-)%s*$')]
frame.args.br, frame.args.result_arg = frame.args.demo_br or frame.args.demo_sep, frame.args.demo_result_arg
local kill_categories = not save_categories
if demoModule then
local named = {insert = function(self, ...) table.insert(self, ...) return self end}
local source = {insert = named.insert, '{{', frame.args.demo_template or frame.args.demo_module, '\n'}
if not template then
source:insert(2, '#invoke:'):insert(4, '|'):insert(5, demoFunc)
end
local insertNamed = #source + 1
for k, v in pairs(orphan.args) do
local nan, insert = type(k) ~= 'number', {v}
local target = nan and named or source
target:insert'|'
if nan then
target:insert(k):insert'=':insert'\n'
table.insert(insert, 1, #target)
end
target:insert(unpack(insert))
local nowiki = v:match('nowiki')
if nowiki or v:match('{{.-}}') then
orphan.args[k] = frame:preprocess(nowiki and mw.text.unstripNoWiki(v) or v)
end
end
source:insert'}}'
table.insert(source, insertNamed, table.concat(named))
return p.main(orphan, {
source = mw.text.encode(table.concat(source), "<>'|=~"),
output = tostring(demoModule(orphan)):gsub(kill_categories and '%[%[Категория:.-%]%]' or '', ''):gsub(kill_categories and '%[%[К:.-%]%]' or '', ''):gsub(kill_categories and '%[%[Category:.-%]%]' or '', ''),
frame = frame
})
else
return "ERROR: Invalid module function: "..demoFunc
end
end
return p
9beaf8f8041a39ae73ba17b2f70609171c4196d3
Шаблон:Государство/doc
10
184
411
410
2024-08-10T15:21:26Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{docpage}}
Этот [[Википедия:Шаблоны-карточки|шаблон-карточка]] используется для вставки карточки в статьи о современных государствах;
* для исторических государств используйте {{t|историческое государство}}.
* для составных частей государств используйте {{t|Административная единица}}.
== Образец для копирования ==
<pre>
{{Государство
|Статус = <!-- виртуальное / непризнанное / частично признанное / регион; для признанных государств не заполнять -->
|Русское название =
|Оригинальное название =
|Родительный падеж =
|Герб =
|Вместо герба =
|Девиз = {{lang-??2|}}<!-- на оф. языке / языках гос-ва -->
|Перевод девиза =
|Название гимна =
|Перевод названия гимна =
|Аудио =
|Форма правления =
|Государственный строй =
|Государственная религия =
|На карте =
|подпись к карте =
|На карте2 =
|Язык/Языки =
|Основано/Основана =
|Дата/Даты независимости =
|Независимость от =
|Столица =
|Крупнейшие города =
|Должность руководителя 1 =
|Руководитель 1 =
|Должность руководителя 2 =
|Руководитель 2 =
|Должность руководителя 3 =
|Руководитель 3 =
|Должность руководителя 4 =
|Руководитель 4 =
|Должность руководителя 5 =
|Руководитель 5 =
|Место по территории =
|Территория =
|Процент воды =
|Этнохороним =
|Место по населению =
|Население =
|Год оценки =
|Население по переписи =
|Год переписи =
|Плотность населения =
|Место по плотности =
|ВВП (ППС) =
|Год расчёта ВВП (ППС) =
|Место по ВВП (ППС) =
|ВВП (ППС) на душу населения =
|Место по ВВП (ППС) на душу населения =
|ВВП (номинал) =
|Год расчёта ВВП (номинал) =
|Место по ВВП (номинал) =
|ВВП (номинал) на душу населения =
|Место по ВВП (номинал) на душу населения =
|ИРЧП =
|Год расчёта ИРЧП =
|Место по ИРЧП =
|Уровень ИРЧП =
|Валюта =
|Домен/Домены =
|Телефонный код =
|Часовой пояс =
|Автомобильное движение =
|Примечания =
<!-- |Без флага и герба=* -->
<!-- |Без гимна=* -->
}}
</pre>
== Описание параметров ==
Некоторые параметры могут быть заданы в разных формах (например, в единственном либо множественном числе). После копирования образца в статью заполните только строку с более подходящей формой. Например, в статье [[Албания]] —
<pre> |Язык = [[Албанский язык|албанский]]</pre>
а в статье [[Канада]] —
<pre> |Языки = [[Английский язык|английский]] и [[Французский язык|французский]]</pre>
Для статей о регионах с нечётким правовым статусом используйте параметр <code>Спорный статус = да</code> и параметры «Основано», «Дата образования», «Провозглашение независимости» и «Дипломатическое признание» вместо «Дата независимости» и «Основано»:
<pre>
|Спорный статус = да
|Основано =
|Основана =
|Дата образования =
|Провозглашение независимости =
|Дипломатическое признание =
|Независимость от =
</pre>
Для статей о [[Непризнанные и частично признанные государства|непризнанных государствах]] или [[Автономный регион|автономных регионах]], не являющихся самостоятельными государствами, используйте параметр <code>Статус = непризнанное</code> или <code>Статус = регион</code>, это отключит автоматическое добавление категории [[:Категория:Государства по алфавиту|Государства по алфавиту]], а в первом случае также добавит категорию [[:Категория:Непризнанные государства|Непризнанные государства]]. Для статей о [[Виртуальное государство|виртуальных государствах]] используйте параметр <code>Статус = виртуальное</code>, это добавит категорию [[:Категория:Виртуальные государства|Виртуальные государства]].
== Пример использования ==
{{demo|reverse=1|br=|<nowiki>{{Государство
|Русское название = Финляндская Республика
|Оригинальное название = {{lang-fi|Suomen Tasavalta}}<br>{{lang-sv|Republiken Finland}}
|Родительный падеж = Финляндии
|Герб = Coat of arms of Finland.svg
|Флаг = Flag of Finland.svg<!-- иначе используется конструкция {{флаг|{{FULLPAGENAME}}|размер=135px}} -->
|Вместо герба =
|Девиз =
|Перевод девиза =
|Название гимна = Maamme
|Перевод названия гимна = Наш край
|Аудио =
|Форма правления = [[президентская республика]]
|Государственный строй = [[унитарное государство]]
|Государственная религия =
|На карте = EU-Finland.svg
|подпись к карте = Расположение '''Финляндии''' (тёмно-зелёный):<br>— в [[Европа|Европе]] (светло-зелёный и тёмно-серый)<br>— в [[Европейский союз|Европейском союзе]] (светло-зелёный)
|На карте2 =
|Языки = [[финский язык|финский]], [[шведский язык|шведский]]
|Основано/Основана =
|Дата независимости = [[6 декабря]] [[1917]]
|Независимость от = [[Россия|России]]
|Столица = [[Хельсинки]]
|Крупнейший город = Хельсинки
|Должность руководителя 1 = [[Президент Финляндии|Президент]]
|Руководитель 1 = [[Халонен, Тарья Каарина|Тарья Халонен]]
|Должность руководителя 2 = [[Премьер-министр Финляндии|Премьер-министр]]
|Руководитель 2 = [[Ванханен, Матти Танели|Матти Ванханен]]
|Место по территории = 63
|Территория = 338 145
|Процент воды = 9,96
|Этнохороним = финляндец, финляндка
|Место по населению = 106
|Население = 5 219 732
|Год оценки = 2003
|Население по переписи =
|Год переписи =
|Плотность населения = 15,4
|Место по плотности =
|ВВП =
|Год расчёта ВВП =
|Место по ВВП =
|ВВП на душу населения =
|Место по ВВП на душу населения =
|ИРЧП =
|Год расчёта ИРЧП =
|Место по ИРЧП =
|Уровень ИРЧП =
|Валюта = [[евро]]<ref name="money">до 2002 — [[финская марка]]</ref>
|Домены = [[.fi]], [[.ax]] (для [[Аландские острова|Аландских островов]])
|Телефонный код = 358
|Часовой пояс = +2
|Автомобильное движение =
|Примечания = <references/>
}}</nowiki>}}
== TemplateData ==
<templatedata>
{
"params": {
"Спорный статус": {},
"Статус": {},
"Русское название": {},
"Оригинальное название": {},
"Флаг": {
"type": "wiki-file-name"
},
"Ссылка на флаг": {},
"Родительный падеж": {},
"Герб": {
"type": "wiki-file-name"
},
"Отображаемая подпись герба": {},
"Вместо герба": {},
"Девиз": {},
"Перевод девиза": {},
"Без гимна": {},
"Название гимна": {},
"Перевод названия гимна": {},
"Аудио": {},
"На карте": {},
"На карте2": {},
"Дата1": {},
"Дата2": {},
"Дата3": {},
"Дата4": {},
"Дата5": {},
"Дата6": {},
"Дата7": {},
"Дата8": {},
"Дата9": {},
"Дата10": {},
"Дата11": {},
"Дата12": {},
"sovereignty_type": {},
"Этап1": {},
"Этап2": {},
"Этап3": {},
"Этап4": {},
"Этап5": {},
"Этап6": {},
"Этап7": {},
"Этап8": {},
"Этап9": {},
"Этап10": {},
"Этап11": {},
"Этап12": {},
"Основана": {},
"Основано": {},
"Дата образования": {},
"Провозглашение независимости": {},
"Независимость от": {},
"Дипломатическое признание": {},
"Отображаемый тип независимости": {},
"Даты независимости": {},
"Дата независимости": {},
"Язык": {},
"Языки": {},
"Столица": {},
"Крупнейший город": {},
"Крупнейшие города": {},
"Форма правления": {},
"Должность руководителя 1": {},
"Должности руководителей": {},
"Руководитель 1": {},
"Руководители": {},
"Должность руководителя 2": {},
"Руководитель 2": {},
"Должность руководителя 3": {},
"Руководитель 3": {},
"Должность руководителя 4": {},
"Руководитель 4": {},
"Должность руководителя 5": {},
"Руководитель 5": {},
"Государственная религия": {},
"Место по территории": {},
"Территория": {},
"Процент воды": {},
"Территория2": {},
"Население": {},
"Год оценки": {},
"Год переписи": {},
"Население2": {},
"Место по населению": {},
"Население по переписи": {},
"Плотность населения": {},
"Место по плотности": {},
"ВВП": {},
"Год расчёта ВВП": {},
"Место по ВВП": {},
"ВВП на душу населения": {},
"Место по ВВП на душу населения": {},
"ВВП (ППС)": {},
"Год расчёта ВВП (ППС)": {},
"Место по ВВП (ППС)": {},
"ВВП (ППС) на душу населения": {},
"Место по ВВП (ППС) на душу населения": {},
"ВВП (номинал)": {},
"Год расчёта ВВП (номинал)": {},
"Место по ВВП (номинал)": {},
"ВВП (номинал) на душу населения": {},
"Место по ВВП (номинал) на душу населения": {},
"Год расчёта ИРЧП": {},
"ИРЧП": {},
"Уровень ИРЧП": {},
"Место по ИРЧП": {},
"Этнохороним": {},
"Валюта": {},
"Домены": {},
"Домен": {},
"Телефонный код": {},
"Часовые пояса": {},
"Часовой пояс": {},
"Примечания": {},
"nocat": {
"type": "boolean"
},
"lat_deg": {},
"lat_min": {},
"lat_sec": {},
"lat_dir": {},
"lon_deg": {},
"lon_min": {},
"lon_sec": {},
"lon_dir": {},
"region": {},
"CoordScale": {},
"Размер герба": {
"aliases": [
"размер герба"
],
"type": "number"
},
"Размер флага": {
"aliases": [
"размер флага"
],
"type": "number"
},
"Размер карты": {
"aliases": [
"размер карты"
]
},
"Подпись к карте": {
"aliases": [
"подпись к карте"
]
},
"Размер карты2": {
"aliases": [
"размер карты2"
]
},
"Государственный строй": {},
"Автомобильное движение": {}
},
"paramOrder": [
"Статус",
"Спорный статус",
"Русское название",
"Оригинальное название",
"Флаг",
"Размер флага",
"Ссылка на флаг",
"Родительный падеж",
"Герб",
"Размер герба",
"Отображаемая подпись герба",
"Вместо герба",
"Девиз",
"Перевод девиза",
"Без гимна",
"Название гимна",
"Перевод названия гимна",
"Аудио",
"На карте",
"Размер карты",
"Подпись к карте",
"На карте2",
"Размер карты2",
"Дата1",
"Дата2",
"Дата3",
"Дата4",
"Дата5",
"Дата6",
"Дата7",
"Дата8",
"Дата9",
"Дата10",
"Дата11",
"Дата12",
"sovereignty_type",
"Этап1",
"Этап2",
"Этап3",
"Этап4",
"Этап5",
"Этап6",
"Этап7",
"Этап8",
"Этап9",
"Этап10",
"Этап11",
"Этап12",
"Основана",
"Основано",
"Дата образования",
"Провозглашение независимости",
"Независимость от",
"Дипломатическое признание",
"Отображаемый тип независимости",
"Даты независимости",
"Дата независимости",
"Язык",
"Языки",
"Столица",
"Крупнейший город",
"Крупнейшие города",
"Форма правления",
"Государственный строй",
"Должность руководителя 1",
"Должности руководителей",
"Руководитель 1",
"Руководители",
"Должность руководителя 2",
"Руководитель 2",
"Должность руководителя 3",
"Руководитель 3",
"Должность руководителя 4",
"Руководитель 4",
"Должность руководителя 5",
"Руководитель 5",
"Государственная религия",
"Место по территории",
"Территория",
"Процент воды",
"Территория2",
"Население",
"Год оценки",
"Год переписи",
"Население2",
"Место по населению",
"Население по переписи",
"Плотность населения",
"Место по плотности",
"ВВП",
"Год расчёта ВВП",
"Место по ВВП",
"ВВП на душу населения",
"Место по ВВП на душу населения",
"ВВП (ППС)",
"Год расчёта ВВП (ППС)",
"Место по ВВП (ППС)",
"ВВП (ППС) на душу населения",
"Место по ВВП (ППС) на душу населения",
"ВВП (номинал)",
"Год расчёта ВВП (номинал)",
"Место по ВВП (номинал)",
"ВВП (номинал) на душу населения",
"Место по ВВП (номинал) на душу населения",
"Год расчёта ИРЧП",
"ИРЧП",
"Уровень ИРЧП",
"Место по ИРЧП",
"Этнохороним",
"Валюта",
"Домены",
"Домен",
"Телефонный код",
"Часовые пояса",
"Часовой пояс",
"Автомобильное движение",
"Примечания",
"lat_deg",
"lat_min",
"lat_sec",
"lat_dir",
"lon_deg",
"lon_min",
"lon_sec",
"lon_dir",
"region",
"CoordScale",
"nocat"
],
"format": "block"
}
</templatedata>
== См. также ==
* {{tl|Историческое государство}}
<includeonly>
[[Категория:Шаблоны-карточки:Географические объекты]]
</includeonly>
b1e2b1107db0671d3bcc4dda5bd29020192c442e
Шаблон:Историческое государство
10
185
413
412
2024-08-10T16:55:56Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{Карточка
|имя = Историческое государство
|from = {{{from|}}}
|стиль_тела = width:28em;
|стиль_заголовков =
|вверху0 = {{#if: {{{статус|}}} | {{{статус}}} | Историческое государство }}
|вверху = {{Карточка/название|{{{название|}}}|from={{{from|}}}}}
|вверху2 = {{Карточка/оригинал названия|{{{самоназвание|}}}|from={{{from|}}}}}
|текст1 = {{Карточка/флаг и герб
| флаг = {{{флаг|}}}
| флаг подпись = {{{описание_флага|}}}
| герб = {{{герб|}}}
| герб подпись = {{{описание_герба|}}}
|from={{{from|}}}}}
|текст2 = {{#if: {{{девиз|}}} | [[Девиз]]: ''«{{{девиз}}}»''{{#if: {{{перевод девиза|}}}|<br />''«{{{перевод девиза}}}»''}} }}
|текст3 = {{if-wikidata|p85|{{{гимн|}}}|[[Государственный гимн|Гимн]]: {{wikidata|p85|{{{гимн|}}}|from={{{from|}}}}}|from={{{from|}}}}}
|викиданные3 = p85
|текст4 = {{wikidata|p242[1]|{{{карта|}}}|size={{{размер|}}}|caption={{{описание|}}}|from={{{from|}}}}}
|заголовок5 = <div style="float:left; margin-right:0.5em; text-align:left; width:4em;"><!--
-->{{#if:{{{p8|}}}{{{successionbelow|}}}|[[#before-after|↓]]|<!--
-->{{#if:{{{p1|}}}|{{nobr|[[{{{p1}}}|←]] {{#if:{{{flag_p1|}}}|[[Файл:{{{flag_p1|}}}|border|30px|link={{{p1|}}}]]|{{#if:{{{image_p1|}}}|{{{image_p1}}}|[[Файл:Flag of None.svg|30px|border]]}}}}}}}}<!--
-->{{#if:{{{p2|}}}|<br>{{nobr|[[{{{p2}}}|←]] {{#if:{{{flag_p2|}}}|[[Файл:{{{flag_p2}}}|border|30px|link={{{p2|}}}]]|{{#if:{{{image_p2|}}}|{{{image_p2}}}|[[Файл:Flag of None.svg|30px|border]]}}}}}}}}<!--
-->{{#if:{{{p3|}}}|<br>{{nobr|[[{{{p3}}}|←]] {{#if:{{{flag_p3|}}}|[[Файл:{{{flag_p3}}}|border|30px|link={{{p3|}}}]]|{{#if:{{{image_p3|}}}|{{{image_p3}}}|[[Файл:Flag of None.svg|30px|border]]}}}}}}}}<!--
-->{{#if:{{{p4|}}}|<br>{{nobr|[[{{{p4}}}|←]] {{#if:{{{flag_p4|}}}|[[Файл:{{{flag_p4}}}|border|30px|link={{{p4|}}}]]|{{#if:{{{image_p4|}}}|{{{image_p4}}}|[[Файл:Flag of None.svg|30px|border]]}}}}}}}}<!--
-->{{#if:{{{p5|}}}|<br>{{nobr|[[{{{p5}}}|←]] {{#if:{{{flag_p5|}}}|[[Файл:{{{flag_p5}}}|border|30px|link={{{p5|}}}]]|{{#if:{{{image_p5|}}}|{{{image_p5}}}|[[Файл:Flag of None.svg|30px|border]]}}}}}}}}<!--
-->{{#if:{{{p6|}}}|<br>{{nobr|[[{{{p6}}}|←]] {{#if:{{{flag_p6|}}}|[[Файл:{{{flag_p6}}}|border|30px|link={{{p6|}}}]]|{{#if:{{{image_p6|}}}|{{{image_p6}}}|[[Файл:Flag of None.svg|30px|border]]}}}}}}}}<!--
-->{{#if:{{{p7|}}}|<br>{{nobr|[[{{{p7}}}|←]] {{#if:{{{flag_p7|}}}|[[Файл:{{{flag_p7}}}|border|30px|link={{{p7|}}}]]|{{#if:{{{image_p7|}}}|{{{image_p7}}}|[[Файл:Flag of None.svg|30px|border]]}}}}}}}}}}<!--
--></div>
<div style="float:right; margin-left:0.5em; text-align:right; width:4em;"><!--
-->{{#if:{{{s8|}}}{{{successionbelow|}}}|[[#before-after|↓]]|<!--
-->{{#if:{{{s1|}}}|{{nobr|{{#if:{{{flag_s1|}}}|[[Файл:{{{flag_s1}}}|border|30px|link={{{s1|}}}]]|{{#if:{{{image_s1|}}}|{{{image_s1}}}|[[Файл:Flag of None.svg|30px|border]]}}}} [[{{{s1}}}|→]]}}}}<!--
-->{{#if:{{{s2|}}}|<br>{{nobr|{{#if:{{{flag_s2|}}}|[[Файл:{{{flag_s2}}}|border|30px|link={{{s2|}}}]]|{{#if:{{{image_s2|}}}|{{{image_s2}}}|[[Файл:Flag of None.svg|30px|border]]}}}} [[{{{s2}}}|→]]}}}}<!--
-->{{#if:{{{s3|}}}|<br>{{nobr|{{#if:{{{flag_s3|}}}|[[Файл:{{{flag_s3}}}|border|30px|link={{{s3|}}}]]|{{#if:{{{image_s3|}}}|{{{image_s3}}}|[[Файл:Flag of None.svg|30px|border]]}}}} [[{{{s3}}}|→]]}}}}<!--
-->{{#if:{{{s4|}}}|<br>{{nobr|{{#if:{{{flag_s4|}}}|[[Файл:{{{flag_s4}}}|border|30px|link={{{s4|}}}]]|{{#if:{{{image_s4|}}}|{{{image_s4}}}|[[Файл:Flag of None.svg|30px|border]]}}}} [[{{{s4}}}|→]]}}}}<!--
-->{{#if:{{{s5|}}}|<br>{{nobr|{{#if:{{{flag_s5|}}}|[[Файл:{{{flag_s5}}}|border|30px|link={{{s5|}}}]]|{{#if:{{{image_s5|}}}|{{{image_s5}}}|[[Файл:Flag of None.svg|30px|border]]}}}} [[{{{s5}}}|→]]}}}}<!--
-->{{#if:{{{s6|}}}|<br>{{nobr|{{#if:{{{flag_s6|}}}|[[Файл:{{{flag_s6}}}|border|30px|link={{{s6|}}}]]|{{#if:{{{image_s6|}}}|{{{image_s6}}}|[[Файл:Flag of None.svg|30px|border]]}}}} [[{{{s6}}}|→]]}}}}<!--
-->{{#if:{{{s7|}}}|<br>{{nobr|{{#if:{{{flag_s7|}}}|[[Файл:{{{flag_s7}}}|border|30px|link={{{s7|}}}]]|{{#if:{{{image_s7|}}}|{{{image_s7}}}|[[Файл:Flag of None.svg|30px|border]]}}}} [[{{{s7}}}|→]]}}}}}}<!--
--></div>
{{#if: {{wikidata|p571|{{{образовано|}}}|plain=true|from={{{from|}}}}} {{wikidata|p576|{{{ликвидировано|}}}|plain=true|from={{{from|}}}}} | <div style="margin:0 4em;">{{nobr|{{wikidata|p571|{{{образовано|}}}|from={{{from|}}}}} —}} {{nobr|{{wikidata|p576|{{{ликвидировано|}}}|from={{{from|}}}}}}}</div> }}
{{-}}
|метка6 = [[Столица]]
|текст6 = {{{столица|}}}
|викиданные6 = p36
|метка7 = Крупнейшие города
|текст7 = {{{города|}}}
|викиданные7 =
|метка8 = Язык(и)
|текст8 = {{{язык|}}}
|викиданные8 = p2936
|метка9 = [[Официальный язык]]
|текст9 = {{{официальный язык|}}}
|викиданные9 = p37
|метка10 = [[Религия]]
|текст10 = {{{религия|}}}
|викиданные10 = p3075
|метка11 = Денежная единица
|текст11 = {{{валюта|}}}
|викиданные11 = p38
|метка12 = Площадь
|текст12 = {{{площадь|}}}
|викиданные12 = p2046
|метка13 = Население
|текст13 = {{{население|}}}
|викиданные13 = p1082
|метка14 = Форма правления
|текст14 = {{{форма_правления|}}}
|викиданные14 = p122
|метка15 = Династия
|текст15 = {{{династия|}}}
|викиданные15 =
|метка16 = {{{дополнительный_параметр}}}
|текст16 = {{{содержимое_параметра|}}}
|викиданные16 =
|метка17 = {{{дополнительный_параметр1}}}
|текст17 = {{{содержимое_параметра1|}}}
|викиданные17 =
|метка18 = {{{дополнительный_параметр2}}}
|текст18 = {{{содержимое_параметра2|}}}
|викиданные18 =
|метка19 = {{{дополнительный_параметр3}}}
|текст19 = {{{содержимое_параметра3|}}}
|викиданные19 =
|метка20 = {{{дополнительный_параметр4}}}
|текст20 = {{{содержимое_параметра4|}}}
|викиданные20 =
|метка21 = {{{дополнительный_параметр5}}}
|текст21 = {{{содержимое_параметра5|}}}
|викиданные21 =
|метка22 = {{{дополнительный_параметр6}}}
|текст22 = {{{содержимое_параметра6|}}}
|викиданные22 =
|заголовок23 = {{#if: {{{титул_правителей2|}}}{{{титул_правителей3|}}}{{{титул_правителей4|}}}{{{титул_правителей5|}}}{{{титул_правителей6|}}}{{{титул_правителей7|}}}{{{титул_правителей8|}}}{{{титул_правителей9|}}}{{{титул_правителей10|}}}{{{титул_правителей11|}}}{{{титул_правителей12|}}}{{{титул_правителей13|}}}{{{титул_правителей14|}}}{{{титул_правителей15|}}}{{{титул_правителей16|}}} | Главы государства }}
|заголовок24 = {{#if: {{{правитель1|}}} | {{{титул_правителя1|{{{титул_правителей}}}}}} }}
|стиль_заголовка24 = {{#if: {{{титул_правителей2|}}}{{{титул_правителей3|}}}{{{титул_правителей4|}}}{{{титул_правителей5|}}}{{{титул_правителей6|}}}{{{титул_правителей7|}}}{{{титул_правителей8|}}}{{{титул_правителей9|}}}{{{титул_правителей10|}}}{{{титул_правителей11|}}}{{{титул_правителей12|}}}{{{титул_правителей13|}}}{{{титул_правителей14|}}}{{{титул_правителей15|}}}{{{титул_правителей16|}}} | background: transparent; padding-bottom:0; border-bottom:0; text-align:left; }}
|метка25 = • {{{год_правителя1}}}
|стиль_метки25 = font-weight:normal; {{#if: {{{титул_правителей2|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст25 = {{{правитель1|}}}
|стиль_текста25 = {{#if: {{{титул_правителей2|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные25 =
|заголовок26 = {{{титул_правителей2|}}}
|стиль_заголовка26 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left;
|метка27 = • {{{год_правителя2}}}
|стиль_метки27 = font-weight:normal; {{#if: {{{титул_правителей3|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст27 = {{{правитель2|}}}
|стиль_текста27 = {{#if: {{{титул_правителей3|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные27 =
|заголовок28 = {{{титул_правителей3|}}}
|стиль_заголовка28 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left;
|метка29 = • {{{год_правителя3}}}
|стиль_метки29 = font-weight:normal; {{#if: {{{титул_правителей4|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст29 = {{{правитель3|}}}
|стиль_текста29 = {{#if: {{{титул_правителей4|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные29 =
|заголовок30 = {{{титул_правителей4|}}}
|стиль_заголовка30 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left;
|метка31 = • {{{год_правителя4}}}
|стиль_метки31 = font-weight:normal; {{#if: {{{титул_правителей5|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст31 = {{{правитель4|}}}
|стиль_текста31 = {{#if: {{{титул_правителей5|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные31 =
|заголовок32 = {{{титул_правителей5|}}}
|стиль_заголовка32 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left;
|метка33 = • {{{год_правителя5}}}
|стиль_метки33 = font-weight:normal; {{#if: {{{титул_правителей6|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст33 = {{{правитель5|}}}
|стиль_текста33 = {{#if: {{{титул_правителей6|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные33 =
|заголовок34 = {{{титул_правителей6|}}}
|стиль_заголовка34 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left;
|метка35 = • {{{год_правителя6}}}
|стиль_метки35 = font-weight:normal; {{#if: {{{титул_правителей7|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст35 = {{{правитель6|}}}
|стиль_текста35 = {{#if: {{{титул_правителей7|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные35 =
|заголовок36 = {{{титул_правителей7|}}}
|стиль_заголовка36 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left;
|метка37 = • {{{год_правителя7}}}
|стиль_метки37 = font-weight:normal; {{#if: {{{титул_правителей8|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст37 = {{{правитель7|}}}
|стиль_текста37 = {{#if: {{{титул_правителей8|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные37 =
|заголовок38 = {{{титул_правителей8|}}}
|стиль_заголовка38 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left;
|метка39 = • {{{год_правителя8}}}
|стиль_метки39 = font-weight:normal; {{#if: {{{титул_правителей9|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст39 = {{{правитель8|}}}
|стиль_текста39 = {{#if: {{{титул_правителей9|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные39 =
|заголовок40 = {{{титул_правителей9|}}}
|стиль_заголовка40 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left;
|метка41 = • {{{год_правителя9}}}
|стиль_метки41 = font-weight:normal; {{#if: {{{титул_правителей10|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст41 = {{{правитель9|}}}
|стиль_текста41 = {{#if: {{{титул_правителей10|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные41 =
|заголовок42 = {{{титул_правителей10|}}}
|стиль_заголовка42 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left;
|метка43 = • {{{год_правителя10}}}
|стиль_метки43 = font-weight:normal; {{#if: {{{титул_правителей11|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст43 = {{{правитель10|}}}
|стиль_текста43 = {{#if: {{{титул_правителей11|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные43 =
|заголовок44 = {{{титул_правителей11|}}}
|стиль_заголовка44 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left;
|метка45 = • {{{год_правителя11}}}
|стиль_метки45 = font-weight:normal; {{#if: {{{титул_правителей12|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст45 = {{{правитель11|}}}
|стиль_текста45 = {{#if: {{{титул_правителей12|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные45 =
|заголовок46 = {{{титул_правителей12|}}}
|стиль_заголовка46 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left;
|метка47 = • {{{год_правителя12}}}
|стиль_метки47 = font-weight:normal; {{#if: {{{титул_правителей13|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст47 = {{{правитель12|}}}
|стиль_текста47 = {{#if: {{{титул_правителей13|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные47 =
|заголовок48 = {{{титул_правителей13|}}}
|стиль_заголовка48 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left;
|метка49 = • {{{год_правителя13}}}
|стиль_метки49 = font-weight:normal; {{#if: {{{титул_правителей14|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст49 = {{{правитель13|}}}
|стиль_текста49 = {{#if: {{{титул_правителей14|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные49 =
|заголовок50 = {{{титул_правителей14|}}}
|стиль_заголовка50 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left;
|метка51 = • {{{год_правителя14}}}
|стиль_метки51 = font-weight:normal; {{#if: {{{титул_правителей15|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст51 = {{{правитель14|}}}
|стиль_текста51 = {{#if: {{{титул_правителей15|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные51 =
|заголовок52 = {{{титул_правителей15|}}}
|стиль_заголовка52 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left;
|метка53 = • {{{год_правителя15}}}
|стиль_метки53 = font-weight:normal; {{#if: {{{титул_правителей16|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст53 = {{{правитель15|}}}
|стиль_текста53 = {{#if: {{{титул_правителей16|}}} | | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные53 =
|заголовок54 = {{{титул_правителей16|}}}
|стиль_заголовка54 = background:transparent; padding-bottom:0; border-bottom:0; text-align:left;
|метка55 = • {{{год_правителя16}}}
|стиль_метки55 = font-weight:normal; padding-top:0; border-top:0;
|текст55 = {{{правитель16|}}}
|стиль_текста55 = padding-top:0; border-top:0;
|викиданные55 =
|заголовок56 = {{#if: {{{Этап1|}}} | История }}
|метка57 = • {{nobr|{{{Дата1|}}}{{#if: {{{Дата1|}}} | {{sp}} }}{{{Год1|}}}}}
|стиль_метки57 = font-weight:normal; {{#if: {{{Этап2|}}} | padding-bottom:0; border-bottom:0;}}
|текст57 = {{{Этап1|}}}
|стиль_текста57 = {{#if: {{{Этап2|}}} | padding-bottom:0; border-bottom:0;}}
|викиданные57 =
|метка58 = • {{nobr|{{{Дата2|}}}{{#if: {{{Дата2|}}} | {{sp}} }}{{{Год2|}}}}}
|стиль_метки58 = font-weight:normal; {{#if: {{{Этап3|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст58 = {{{Этап2|}}}
|стиль_текста58 = {{#if: {{{Этап3|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные58 =
|метка59 = • {{nobr|{{{Дата3|}}}{{#if: {{{Дата3|}}} | {{sp}} }}{{{Год3|}}}}}
|стиль_метки59 = font-weight:normal; {{#if: {{{Этап4|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст59 = {{{Этап3|}}}
|стиль_текста59 = {{#if: {{{Этап4|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные59 =
|метка60 = • {{nobr|{{{Дата4|}}}{{#if: {{{Дата4|}}} | {{sp}} }}{{{Год4|}}}}}
|стиль_метки60 = font-weight:normal; {{#if: {{{Этап5|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст60 = {{{Этап4|}}}
|стиль_текста60 = {{#if: {{{Этап5|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные60 =
|метка61 = • {{nobr|{{{Дата5|}}}{{#if: {{{Дата5|}}} | {{sp}} }}{{{Год5|}}}}}
|стиль_метки61 = font-weight:normal; {{#if: {{{Этап6|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст61 = {{{Этап5|}}}
|стиль_текста61 = {{#if: {{{Этап6|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные61 =
|метка62 = • {{nobr|{{{Дата6|}}}{{#if: {{{Дата6|}}} | {{sp}} }}{{{Год6|}}}}}
|стиль_метки62 = font-weight:normal; {{#if: {{{Этап7|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст62 = {{{Этап6|}}}
|стиль_текста62 = {{#if: {{{Этап7|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные62 =
|метка63 = • {{nobr|{{{Дата7|}}}{{#if: {{{Дата7|}}} | {{sp}} }}{{{Год7|}}}}}
|стиль_метки63 = font-weight:normal; {{#if: {{{Этап8|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст63 = {{{Этап7|}}}
|стиль_текста63 = {{#if: {{{Этап8|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные63 =
|метка64 = • {{nobr|{{{Дата8|}}}{{#if: {{{Дата8|}}} | {{sp}} }}{{{Год8|}}}}}
|стиль_метки64 = font-weight:normal; {{#if: {{{Этап9|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст64 = {{{Этап8|}}}
|стиль_текста64 = {{#if: {{{Этап9|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные64 =
|метка65 = • {{nobr|{{{Дата9|}}}{{#if: {{{Дата9|}}} | {{sp}} }}{{{Год9|}}}}}
|стиль_метки65 = font-weight:normal; {{#if: {{{Этап10|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст65 = {{{Этап9|}}}
|стиль_текста65 = {{#if: {{{Этап10|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные65 =
|метка66 = • {{nobr|{{{Дата10|}}}{{#if: {{{Дата10|}}} | {{sp}} }}{{{Год10|}}}}}
|стиль_метки66 = font-weight:normal; {{#if: {{{Этап11|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|текст66 = {{{Этап10|}}}
|стиль_текста66 = {{#if: {{{Этап11|}}} | padding-bottom:0; border-bottom:0;}} padding-top:0; border-top:0;
|викиданные66 =
|метка67 = • {{nobr|{{{Дата11|}}}{{#if: {{{Дата11|}}} | {{sp}} }}{{{Год11|}}}}}
|стиль_метки67 = font-weight:normal; padding-top:0; border-top:0;
|текст67 = {{{Этап11|}}}
|стиль_текста67 = padding-top:0; border-top:0;
|викиданные67 =
|заголовок68 = {{#if: {{{до|}}}{{{после|}}} | Преемственность }}
|текст69 = {{#if: {{{до|}}} | ← [[{{{до}}}]]
{{#if: {{{д1|}}} | ← [[{{{д1}}}]] }}
{{#if: {{{д2|}}} | ← [[{{{д2}}}]] }}
{{#if: {{{д3|}}} | ← [[{{{д3}}}]] }}
{{#if: {{{д4|}}} | ← [[{{{д4}}}]] }}
{{#if: {{{д5|}}} | ← [[{{{д5}}}]] }}
{{#if: {{{д6|}}} | ← [[{{{д6}}}]] }}
{{#if: {{{д7|}}} | ← [[{{{д7}}}]] }}
}}
|стиль_текста69 = text-align:left;
|текст70 = {{#if: {{{после|}}} | [[{{{после}}}]] →
{{#if: {{{п1|}}} | [[{{{п1}}}]] → }}
{{#if: {{{п2|}}} | [[{{{п2}}}]] → }}
{{#if: {{{п3|}}} | [[{{{п3}}}]] → }}
{{#if: {{{п4|}}} | [[{{{п4}}}]] → }}
{{#if: {{{п5|}}} | [[{{{п5}}}]] → }}
{{#if: {{{п6|}}} | [[{{{п6}}}]] → }}
{{#if: {{{п7|}}} | [[{{{п7}}}]] → }}
}}
|стиль_текста70 = text-align:right;
|заголовок71 = {{#ifeq: {{#expr: {{#expr:{{#if:{{{p8|}}}|1|0}}+{{#if:{{{s8|}}}|1|0}}}}+{{#if:{{{successionbelow|}}}|1|0}} > 0}} | 1 | {{Видимый якорь|before-after|текст=Предшественники и преемники}} }}
|текст72 = {{#ifeq: {{#expr: {{#expr:{{#if:{{{p8|}}}|1|0}}+{{#if:{{{s8|}}}|1|0}}}}+{{#if:{{{successionbelow|}}}|1|0}} > 0}} | 1 | <table style="display:table; margin:0; padding:0; table-layout:fixed; width:100%;">
<tr>
<td style="padding-left:0;">{{#if: {{{p1|}}}{{{successionbelow|}}} |
{{#if: {{{type_before|}}}{{{type_after|}}} | '''{{{type_before|Предшественники}}}''' }}
* {{#if:{{{flag_p1|}}}|[[Файл:{{{flag_p1}}}|20px|border]]|{{#if:{{{image_p1|}}}|{{{image_p1}}}}}}} [[{{{p1}}}]]<!--
-->{{#if: {{{p2|}}} | * {{#if:{{{flag_p2|}}}|[[Файл:{{{flag_p2}}}|20px|border]]|{{#if:{{{image_p2|}}}|{{{image_p2}}}}}}} [[{{{p2}}}]] }}<!--
-->{{#if: {{{p3|}}} | * {{#if:{{{flag_p3|}}}|[[Файл:{{{flag_p3}}}|20px|border]]|{{#if:{{{image_p3|}}}|{{{image_p3}}}}}}} [[{{{p3}}}]] }}<!--
-->{{#if: {{{p4|}}} | * {{#if:{{{flag_p4|}}}|[[Файл:{{{flag_p4}}}|20px|border]]|{{#if:{{{image_p4|}}}|{{{image_p4}}}}}}} [[{{{p4}}}]] }}<!--
-->{{#if: {{{p5|}}} | * {{#if:{{{flag_p5|}}}|[[Файл:{{{flag_p5}}}|20px|border]]|{{#if:{{{image_p5|}}}|{{{image_p5}}}}}}} [[{{{p5}}}]] }}<!--
-->{{#if: {{{p6|}}} | * {{#if:{{{flag_p6|}}}|[[Файл:{{{flag_p6}}}|20px|border]]|{{#if:{{{image_p6|}}}|{{{image_p6}}}}}}} [[{{{p6}}}]] }}<!--
-->{{#if: {{{p7|}}} | * {{#if:{{{flag_p7|}}}|[[Файл:{{{flag_p7}}}|20px|border]]|{{#if:{{{image_p7|}}}|{{{image_p7}}}}}}} [[{{{p7}}}]] }}<!--
-->{{#if: {{{p8|}}} | * {{#if:{{{flag_p8|}}}|[[Файл:{{{flag_p8}}}|20px|border]]|{{#if:{{{image_p8|}}}|{{{image_p8}}}}}}} [[{{{p8}}}]] }}<!--
-->{{#if: {{{p9|}}} | * {{#if:{{{flag_p9|}}}|[[Файл:{{{flag_p9}}}|20px|border]]|{{#if:{{{image_p9|}}}|{{{image_p9}}}}}}} [[{{{p9}}}]] }}<!--
-->{{#if: {{{p10|}}} | * {{#if:{{{flag_p10|}}}|[[Файл:{{{flag_p10}}}|20px|border]]|{{#if:{{{image_p10|}}}|{{{image_p10}}}}}}} [[{{{p10}}}]] }}<!--
-->{{#if: {{{p11|}}} | * {{#if:{{{flag_p11|}}}|[[Файл:{{{flag_p11}}}|20px|border]]|{{#if:{{{image_p11|}}}|{{{image_p11}}}}}}} [[{{{p11}}}]] }}<!--
-->{{#if: {{{p12|}}} | * {{#if:{{{flag_p12|}}}|[[Файл:{{{flag_p12}}}|20px|border]]|{{#if:{{{image_p12|}}}|{{{image_p12}}}}}}} [[{{{p12}}}]] }}<!--
-->{{#if: {{{p13|}}} | * {{#if:{{{flag_p13|}}}|[[Файл:{{{flag_p13}}}|20px|border]]|{{#if:{{{image_p13|}}}|{{{image_p13}}}}}}} [[{{{p13}}}]] }}<!--
-->{{#if: {{{p14|}}} | * {{#if:{{{flag_p14|}}}|[[Файл:{{{flag_p14}}}|20px|border]]|{{#if:{{{image_p14|}}}|{{{image_p14}}}}}}} [[{{{p14}}}]] }}<!--
-->{{#if: {{{p15|}}} | * {{#if:{{{flag_p15|}}}|[[Файл:{{{flag_p15}}}|20px|border]]|{{#if:{{{image_p15|}}}|{{{image_p15}}}}}}} [[{{{p15}}}]] }}
}}</td>
<td style="padding-right:0;">{{#if: {{{s1|}}}{{{successionbelow|}}} |
{{#if: {{{type_before|}}}{{{type_after|}}} | '''{{{type_after|Преемники}}}''' }}
* {{#if:{{{flag_s1|}}}|[[Файл:{{{flag_s1}}}|20px|border]]|{{#if:{{{image_s1|}}}|{{{image_s1}}}}}}} [[{{{s1}}}]]<!--
-->{{#if: {{{s2|}}} | * {{#if:{{{flag_s2|}}}|[[Файл:{{{flag_s2}}}|20px|border]]|{{#if:{{{image_s2|}}}|{{{image_s2}}}}}}} [[{{{s2}}}]] }}<!--
-->{{#if: {{{s3|}}} | * {{#if:{{{flag_s3|}}}|[[Файл:{{{flag_s3}}}|20px|border]]|{{#if:{{{image_s3|}}}|{{{image_s3}}}}}}} [[{{{s3}}}]] }}<!--
-->{{#if: {{{s4|}}} | * {{#if:{{{flag_s4|}}}|[[Файл:{{{flag_s4}}}|20px|border]]|{{#if:{{{image_s4|}}}|{{{image_s4}}}}}}} [[{{{s4}}}]] }}<!--
-->{{#if: {{{s5|}}} | * {{#if:{{{flag_s5|}}}|[[Файл:{{{flag_s5}}}|20px|border]]|{{#if:{{{image_s5|}}}|{{{image_s5}}}}}}} [[{{{s5}}}]] }}<!--
-->{{#if: {{{s6|}}} | * {{#if:{{{flag_s6|}}}|[[Файл:{{{flag_s6}}}|20px|border]]|{{#if:{{{image_s6|}}}|{{{image_s6}}}}}}} [[{{{s6}}}]] }}<!--
-->{{#if: {{{s7|}}} | * {{#if:{{{flag_s7|}}}|[[Файл:{{{flag_s7}}}|20px|border]]|{{#if:{{{image_s7|}}}|{{{image_s7}}}}}}} [[{{{s7}}}]] }}<!--
-->{{#if: {{{s8|}}} | * {{#if:{{{flag_s8|}}}|[[Файл:{{{flag_s8}}}|20px|border]]|{{#if:{{{image_s8|}}}|{{{image_s8}}}}}}} [[{{{s8}}}]] }}<!--
-->{{#if: {{{s9|}}} | * {{#if:{{{flag_s9|}}}|[[Файл:{{{flag_s9}}}|20px|border]]|{{#if:{{{image_s9|}}}|{{{image_s9}}}}}}} [[{{{s9}}}]] }}<!--
-->{{#if: {{{s10|}}} | * {{#if:{{{flag_s10|}}}|[[Файл:{{{flag_s10}}}|20px|border]]|{{#if:{{{image_s10|}}}|{{{image_s10}}}}}}} [[{{{s10}}}]] }}<!--
-->{{#if: {{{s11|}}} | * {{#if:{{{flag_s11|}}}|[[Файл:{{{flag_s11}}}|20px|border]]|{{#if:{{{image_s11|}}}|{{{image_s11}}}}}}} [[{{{s11}}}]] }}<!--
-->{{#if: {{{s12|}}} | * {{#if:{{{flag_s12|}}}|[[Файл:{{{flag_s12}}}|20px|border]]|{{#if:{{{image_s12|}}}|{{{image_s12}}}}}}} [[{{{s12}}}]] }}<!--
-->{{#if: {{{s13|}}} | * {{#if:{{{flag_s13|}}}|[[Файл:{{{flag_s13}}}|20px|border]]|{{#if:{{{image_s13|}}}|{{{image_s13}}}}}}} [[{{{s13}}}]] }}<!--
-->{{#if: {{{s14|}}} | * {{#if:{{{flag_s14|}}}|[[Файл:{{{flag_s14}}}|20px|border]]|{{#if:{{{image_s14|}}}|{{{image_s14}}}}}}} [[{{{s14}}}]] }}<!--
-->{{#if: {{{s15|}}} | * {{#if:{{{flag_s15|}}}|[[Файл:{{{flag_s15}}}|20px|border]]|{{#if:{{{image_s15|}}}|{{{image_s15}}}}}}} [[{{{s15}}}]] }}
}}</td>
</tr>
</table> }}
|стиль_текста72 = text-align:left;
|текст73 = {{{прим|}}}
|стиль_текста73 = border-top:1px solid #a2a9b1; color:#54595d; padding-top:0.5em; text-align:left;
|внизу = {{карточка/Викисклад|{{{викисклад|}}}|from={{{from|}}}}}
}}{{#if:{{NAMESPACE}}{{{nocat|}}}||<!--
-->{{категория по дате|{{{образовано|}}}|Государства и территории, основанные|p571|from={{{from|}}}}}<!--
-->{{категория по дате|{{{образовано2|}}}|Государства и территории, основанные|from={{{from|}}}}}<!--
-->{{категория по дате|{{{образовано3|}}}|Государства и территории, основанные|from={{{from|}}}}}<!--
-->{{категория по дате|{{{ликвидировано|}}}|Государства и территории, исчезнувшие|p576|from={{{from|}}}}}<!--
-->{{категория по дате|{{{ликвидировано2|}}}|Государства и территории, исчезнувшие|from={{{from|}}}}}<!--
-->{{категория по дате|{{{ликвидировано3|}}}|Государства и территории, исчезнувшие|from={{{from|}}}}}<!--
-->{{#ifeq:{{{флаг}}}|novalue|{{#if:{{wikidata|p41|from={{{from|}}}}}|[[Категория:Статьи со спорным параметром в Викиданных]]}}|}}{{#ifeq:{{{герб}}}|novalue|{{#if:{{if-wikidata|p94|from={{{from|}}}}}|[[Категория:Статьи со спорным параметром в Викиданных]]}}|}}<!--
-->}}<noinclude>{{doc}}</noinclude>
3f810e404f545118ca6d15a13a0a04829c1f3c88
Модуль:Category handler
828
31
415
49
2024-08-10T16:55:58Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
--------------------------------------------------------------------------------
-- --
-- CATEGORY HANDLER --
-- --
-- This module implements the {{category handler}} template in Lua, --
-- with a few improvements: all namespaces and all namespace aliases --
-- are supported, and namespace names are detected automatically for --
-- the local wiki. This module requires [[Module:Namespace detect]] --
-- and [[Module:Yesno]] to be available on the local wiki. It can be --
-- configured for different wikis by altering the values in --
-- [[Module:Category handler/config]], and pages can be blacklisted --
-- from categorisation by using [[Module:Category handler/blacklist]]. --
-- --
--------------------------------------------------------------------------------
-- Load required modules
local yesno = require('Module:Yesno')
-- Lazily load things we don't always need
local mShared, mappings
local p = {}
--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------
local function trimWhitespace(s, removeBlanks)
if type(s) ~= 'string' then
return s
end
s = s:match('^%s*(.-)%s*$')
if removeBlanks then
if s ~= '' then
return s
else
return nil
end
else
return s
end
end
--------------------------------------------------------------------------------
-- CategoryHandler class
--------------------------------------------------------------------------------
local CategoryHandler = {}
CategoryHandler.__index = CategoryHandler
function CategoryHandler.new(data, args)
local obj = setmetatable({ _data = data, _args = args }, CategoryHandler)
-- Set the title object
do
local pagename = obj:parameter('demopage')
local success, titleObj
if pagename then
success, titleObj = pcall(mw.title.new, pagename)
end
if success and titleObj then
obj.title = titleObj
if titleObj == mw.title.getCurrentTitle() then
obj._usesCurrentTitle = true
end
else
obj.title = mw.title.getCurrentTitle()
obj._usesCurrentTitle = true
end
end
-- Set suppression parameter values
for _, key in ipairs{'nocat', 'categories'} do
local value = obj:parameter(key)
value = trimWhitespace(value, true)
obj['_' .. key] = yesno(value)
end
do
local subpage = obj:parameter('subpage')
local category2 = obj:parameter('category2')
if type(subpage) == 'string' then
subpage = mw.ustring.lower(subpage)
end
if type(category2) == 'string' then
subpage = mw.ustring.lower(category2)
end
obj._subpage = trimWhitespace(subpage, true)
obj._category2 = trimWhitespace(category2) -- don't remove blank values
end
return obj
end
function CategoryHandler:parameter(key)
local parameterNames = self._data.parameters[key]
local pntype = type(parameterNames)
if pntype == 'string' or pntype == 'number' then
return self._args[parameterNames]
elseif pntype == 'table' then
for _, name in ipairs(parameterNames) do
local value = self._args[name]
if value ~= nil then
return value
end
end
return nil
else
error(string.format(
'invalid config key "%s"',
tostring(key)
), 2)
end
end
function CategoryHandler:isSuppressedByArguments()
return
-- See if a category suppression argument has been set.
self._nocat == true
or self._categories == false
or (
self._category2
and self._category2 ~= self._data.category2Yes
and self._category2 ~= self._data.category2Negative
)
-- Check whether we are on a subpage, and see if categories are
-- suppressed based on our subpage status.
or self._subpage == self._data.subpageNo and self.title.isSubpage
or self._subpage == self._data.subpageOnly and not self.title.isSubpage
end
function CategoryHandler:shouldSkipBlacklistCheck()
-- Check whether the category suppression arguments indicate we
-- should skip the blacklist check.
return self._nocat == false
or self._categories == true
or self._category2 == self._data.category2Yes
end
function CategoryHandler:matchesBlacklist()
if self._usesCurrentTitle then
return self._data.currentTitleMatchesBlacklist
else
mShared = mShared or require('Module:Category handler/shared')
return mShared.matchesBlacklist(
self.title.prefixedText,
mw.loadData('Module:Category handler/blacklist')
)
end
end
function CategoryHandler:isSuppressed()
-- Find if categories are suppressed by either the arguments or by
-- matching the blacklist.
return self:isSuppressedByArguments()
or not self:shouldSkipBlacklistCheck() and self:matchesBlacklist()
end
function CategoryHandler:getNamespaceParameters()
if self._usesCurrentTitle then
return self._data.currentTitleNamespaceParameters
else
if not mappings then
mShared = mShared or require('Module:Category handler/shared')
mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData
end
return mShared.getNamespaceParameters(
self.title,
mappings
)
end
end
function CategoryHandler:namespaceParametersExist()
-- Find whether any namespace parameters have been specified.
-- We use the order "all" --> namespace params --> "other" as this is what
-- the old template did.
if self:parameter('all') then
return true
end
if not mappings then
mShared = mShared or require('Module:Category handler/shared')
mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData
end
for ns, params in pairs(mappings) do
for i, param in ipairs(params) do
if self._args[param] then
return true
end
end
end
if self:parameter('other') then
return true
end
return false
end
function CategoryHandler:getCategories()
local params = self:getNamespaceParameters()
local nsCategory
for i, param in ipairs(params) do
local value = self._args[param]
if value ~= nil then
nsCategory = value
break
end
end
if nsCategory ~= nil or self:namespaceParametersExist() then
-- Namespace parameters exist - advanced usage.
if nsCategory == nil then
nsCategory = self:parameter('other')
end
local ret = {self:parameter('all')}
local numParam = tonumber(nsCategory)
if numParam and numParam >= 1 and math.floor(numParam) == numParam then
-- nsCategory is an integer
ret[#ret + 1] = self._args[numParam]
else
ret[#ret + 1] = nsCategory
end
if #ret < 1 then
return nil
else
return table.concat(ret)
end
elseif self._data.defaultNamespaces[self.title.namespace] then
-- Namespace parameters don't exist, simple usage.
return self._args[1]
end
return nil
end
--------------------------------------------------------------------------------
-- Exports
--------------------------------------------------------------------------------
local p = {}
function p._exportClasses()
-- Used for testing purposes.
return {
CategoryHandler = CategoryHandler
}
end
function p._main(args, data)
data = data or mw.loadData('Module:Category handler/data')
local handler = CategoryHandler.new(data, args)
if handler:isSuppressed() then
return nil
end
return handler:getCategories()
end
function p.main(frame, data)
data = data or mw.loadData('Module:Category handler/data')
local args = require('Module:Arguments').getArgs(frame, {
wrappers = data.wrappers,
valueFunc = function (k, v)
v = trimWhitespace(v)
if type(k) == 'number' then
if v ~= '' then
return v
else
return nil
end
else
return v
end
end
})
return p._main(args, data)
end
return p
b74dd63857b24904ac452429b11213f18647471f
Модуль:Wikidata/number
828
186
417
416
2024-08-10T16:56:04Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
local p = {}
function p.formatVisualMagnitude ( context, options )
if ( not context ) then error( 'context not specified' ); end;
if ( not options ) then error( 'options not specified' ); end;
min = context.selectClaims( options, 'P1215[P1227:Q76596947][rank:normal,rank:preferred]' )
max = context.selectClaims( options, 'P1215[P1227:Q76596417][rank:normal,rank:preferred]' )
if ( not min or not max) then -- показываем как обычно
return context.formatPropertyDefault( context, options )
end
-- показываем Vmin-Vmax для переменной звезды
local lang = mw.language.getContentLanguage();
for _, claim1 in ipairs(min) do
for _, claim2 in ipairs(max) do
return lang:formatNum(tonumber(claim1.mainsnak.datavalue.value.amount))
.. ' − ' ..
lang:formatNum(tonumber(claim2.mainsnak.datavalue.value.amount))
end
end
end
function p.formatColorIndex( context, options )
if ( not context ) then error( 'context not specified' ); end;
if ( not options ) then error( 'options not specified' ); end;
if ( options.property ) then
-- Пролучаем все claims независимо от ранга
claims = context.selectClaims( options, options.property .. '[rank:normal,rank:preferred]' );
end
if ( claims ) then
return context.formatPropertyDefault( context, options )
end
-- Вычисляем B-V либо U-B из P1215
b = context.selectClaims( options, 'P1215[P1227:Q6746395][rank:normal,rank:preferred]' )
if ( not b ) then return end
if string.find( options.property, 'Q17773035' ) then
m1 = context.selectClaims( options, 'P1215[P1227:Q15977921][rank:normal,rank:preferred]' )
m2 = b
if ( not m1 ) then return end
else
m1 = b
m2 = context.selectClaims( options, 'P1215[P1227:Q4892529][rank:normal,rank:preferred]' )
if ( not m2 ) then return end
end
for _, claim1 in ipairs(m1) do
for _, claim2 in ipairs(m2) do
newClaim = { mainsnak = { snaktype = 'value', datavalue = { type = 'quantity',
value = { unit = '1', amount = claim1.mainsnak.datavalue.value.amount -
claim2.mainsnak.datavalue.value.amount }}}}
return context.formatStatementDefault( context, options, newClaim )
end
end
end
function p.formatPropertyWithMostRecentClaimAndIndicator( context, options )
if ( not context ) then error( 'context not specified' ); end;
if ( not options ) then error( 'options not specified' ); end;
if ( not options.entity ) then error( 'options.entity missing' ); end;
local claims;
if options.property then
-- Пролучаем все claims независимо от ранга
claims = context.selectClaims( options, options.property .. '[rank:normal,rank:preferred]' );
end
if claims == nil then
return ''
end
-- Ищем claim с максимальным значением P585 и форматируем его в out
local maxTimestamp = nil;
local mostRecentClaim;
for i, claim in ipairs(claims) do
if (claim.qualifiers and claim.qualifiers.P585) then -- обрабатываем только claims с указанным P585
local timestamp = context.parseTimeFromSnak( claim.qualifiers.P585[1] );
if timestamp ~= nil and ( maxTimestamp == nil or maxTimestamp < timestamp ) then
maxTimestamp = timestamp;
mostRecentClaim = claim
end
end
end
if (not mostRecentClaim) then -- нет ни одного claim с указанным P585
return context.formatPropertyDefault( context, options )
end
local out = context.formatStatement( options, mostRecentClaim )
if out ~= '' then
-- Ищем claim со значением P585 сразу после максимального и запоминаем его в secondMostRecentValue
local secondMostRecentTimestamp = 0;
local secondMostRecentValue = 0;
for i, claim in ipairs(claims) do
if (claim.qualifiers and claim.qualifiers.P585) then -- обрабатываем только claims с указанным P585
local timestamp = context.parseTimeFromSnak( claim.qualifiers.P585[1] )
if (timestamp ~= nil and secondMostRecentTimestamp < timestamp and maxTimestamp > timestamp) then
secondMostRecentTimestamp = timestamp
secondMostRecentValue = tonumber( claim.mainsnak.datavalue.value.amount )
end
end
end
if (secondMostRecentValue ~= 0) then -- если предыдущее значение нашлось
if (secondMostRecentValue < tonumber( mostRecentClaim.mainsnak.datavalue.value.amount )) then
out = '<span style="color: #0c0; font-size: larger;">▲</span>' .. out
else
out = '<span style="color: red; font-size: larger;">▼</span>' .. out
end
end
if options.before then
out = options.before .. out
end
if options.after then
out = out .. options.after
end
end
return out
end
function p.formatQuantityWithDateClaim( context, options, statement )
local snak = context.formatSnak( options, statement.mainsnak )
if not snak then return '' end
--Date
if ( statement.qualifiers and statement.qualifiers.P585 ) then
snak = snak .. ' (' .. context.formatSnak( options, statement.qualifiers.P585[1] ) .. ')'
end
--References
if ( options.references ) then
snak = snak .. context.formatRefs( options, statement );
end
return snak
end
function p.formatDMS( context, options, value )
if not value.amount then return value end
if options and options.unit == '-' then return value.amount end
local prefix = "+"
if tonumber( value.amount ) < 0 then
prefix = "−"
end
return p.formatAngle ( math.abs( tonumber( value.amount ) ),
string.len( value.amount ) - string.find( value.amount, '.', 1, true ) - 5,
prefix .. "%s° %02d′ %s″")
end
function p.formatRA( context, options, value )
if not value.amount then return value end
if options and options.unit == '-' then return value.amount end
return p.formatAngle (tonumber( value.amount ) / 15,
string.len( value.amount ) - string.find( value.amount, '.', 1, true ) - 4,
"%s<sup>ч</sup> %02d<sup>м</sup> %s<sup>с</sup>")
end
function p.formatAngle ( angle, sig, format )
local d, angle = math.modf( angle )
local m, angle = math.modf( angle * 60 )
local mult = 10 ^ sig;
local s = math.floor( angle * 60 * mult + 0.5 ) / mult;
local lang = mw.language.getContentLanguage();
return string.format( format, d, m, lang:formatNum( s ) )
end
return p
2f96549583b299597b7f95fbceeddad31ccee753
Шаблон:No-doc
10
187
419
418
2024-08-10T16:56:06Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{#ifeq: {{SUBPAGENAME}} | doc
|| {{#if: {{#if: {{yesno|{{{nocat|}}}}} | x }}{{#switch: {{NAMESPACE}} | {{ns:10}} | {{ns:828}} = | x }}
|| {{{1|}}}
}}
}}<noinclude>{{doc}}</noinclude>
da013ca5b5f97f94bee392ff3a4488046f2ceac7
Шаблон:Clear
10
188
421
420
2024-08-10T16:56:09Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<div style="clear:{{{1|both}}};"></div><noinclude>{{doc}}</noinclude>
15e943687be5d8f8e27fa6cc7813bbfa85df72a9
Шаблон:-
10
189
423
422
2024-08-10T16:56:10Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
#перенаправление [[Шаблон:Clear]]
f3ec5262c8fab1ae984101008632fb9c091fb431
Шаблон:Ombox
10
20
425
38
2024-08-10T16:56:11Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{#invoke:Message box|ombox}}<noinclude>
{{doc}}<!-- Add categories and interwikis to the /doc subpage, not here! --></noinclude>
ab34435c5ebc29de589c9b059e88da5d0e6f16e4
Шаблон:Переписать шаблон
10
190
427
426
2024-08-10T16:56:12Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{ombox
|type = style
|text = '''Этот шаблон следует переписать{{#if: {{{меташаблон|}}} | с использованием меташаблона {{tl|{{{меташаблон}}}}} }}.''' <div style="font-size:95%;">{{#if: {{{меташаблон|}}} | Использование меташаблонов позволяет более полно использовать возможности шаблонов (см. [[Википедия:Рекомендации по созданию шаблонов]])|См. также [[Википедия:Рекомендации по созданию шаблонов]].}}</div>
}}<includeonly>{{no-doc|nocat={{{nocat|}}}|{{#switch: {{lc: {{{меташаблон|}}} }}
| карточка = [[Категория:Википедия:Шаблоны для перевода на карточку]]
| навигационная таблица = [[Категория:Википедия:Шаблоны для перевода на навигационную таблицу]]
| статья проекта = [[Категория:Википедия:Шаблоны для перевода на статью проекта]]
| ае | административная единица = [[Категория:Википедия:Шаблоны для перевода на шаблон АЕ]]
| [[Категория:Википедия:Шаблоны к переработке]]
}}
{{#switch: {{lc: {{{меташаблон|}}} }}
| карточка | карточка персонажа | ае | административная единица | воинское формирование ссср | карточка/блок = [[Категория:Шаблоны-карточки по алфавиту]]
}}
}}</includeonly><noinclude>{{doc}}</noinclude>
cb8733e779fa70731f445053204e92dc5afa0ebb
Шаблон:Историческое государство/doc
10
191
429
428
2024-08-10T16:56:12Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{docpage}}
{{Переписать шаблон|меташаблон=Карточка/блок с маркерами}}
Этот [[Википедия:Шаблоны-карточки|шаблон-карточка]] используется для вставки карточки в статьи об отдельных исторических государствах.
* для современных государств используется {{t|государство}}.
* для составных частей государств используется {{t|административная единица}}.
== Заготовка, включающая все возможные параметры ==
<pre>
{{Историческое государство
|название =
|самоназвание =
|статус =
|гимн =
|флаг =
|описание_флага =
|герб =
|описание_герба =
|карта =
|размер =
|описание =
<!-- |type_before = если этот параметр присутствует в шаблоне,
то необходимо указать примерно следующее: «Государства-основатели»,
иначе удалите его, автоматически будет указано: «Предшественники».-->
|p1 =
|flag_p1 =
|image_p1 =
|p2 =
|flag_p2 =
|image_p2 =
|p3 =
|flag_p3 =
|image_p3 =
|p4 =
|flag_p4 =
|image_p4 =
|образовано =
|ликвидировано =
<!-- |type_after = если этот параметр присутствует в шаблоне,
то необходимо указать примерно следующее: «Государства после распада…»,
иначе удалите его, автоматически будет указано: «Преемники».-->
|s1 =
|flag_s1 =
|image_s1 =
|s2 =
|flag_s2 =
|image_s2 =
|s3 =
|flag_s3 =
|image_s3 =
|s4 =
|flag_s4 =
|image_s4 =
|девиз =
|столица =
|города =
|язык =
|валюта =
|дополнительный_параметр =
|содержимое_параметра =
|площадь =
|население =
|форма_правления =
|династия =
|титул_правителей =
|правитель1 = <!--Не вставляйте в шаблон всех правителей, если их много — он не для этого! Создайте соответствующий раздел в статье. -->
|год_правителя1 =
|титул_правителей2 = <!--используется при изменении титула последующего правителя-->
|правитель2 =
|год_правителя2 =
|титул_правителей3 =
|правитель3 =
|год_правителя3 =
|титул_правителей4 =
|правитель4 =
|год_правителя4 =
|титул_правителей5 =
|правитель5 =
|год_правителя5 =
|титул_правителей6 =
|правитель6 =
|год_правителя6 =
|религия =
|дополнительный_параметр1 =
|содержимое_параметра1 =
|Этап1 =
|Дата1 =
|Год1 =
|Этап2 =
|Дата2 =
|Год2 =
|Этап3 =
|Дата3 =
|Год3 =
|Этап4 =
|Дата4 =
|Год4 =
|Этап5 =
|Дата5 =
|Год5 =
|Этап6 =
|Дата6 =
|Год6 =
|Этап7 =
|Дата7 =
|Год7 =
|Этап8 =
|Дата8 =
|Год8 =
|Этап9 =
|Дата9 =
|Год9 =
|Этап10 =
|Дата10 =
|Год10 =
|Этап11 =
|Дата11 =
|Год11 =
|дополнительный_параметр2 =
|содержимое_параметра2 =
|до =
|д1 =
|д2 =
|д3 =
|д4 =
|д5 =
|д6 =
|д7 =
|после =
|п1 =
|п2 =
|п3 =
|п4 =
|п5 =
|п6 =
|п7 =
|прим =
|викисклад =
}}
</pre>
* ''Название'' — официальное наименование административной единицы (если административная единица имела несколько официальных наименований — указывается то, что применялось на протяжении наибольшего времени существования территории).
* ''Самоназвание'' — название на официальном языке административной единицы.
* ''Статус'' — административный статус единицы (царство, княжество, королевство и т. д.).
* ''Гимн'' — гимн территории. Параметр поддерживает импорт викиданных.
* ''Флаг'' — флаг территории. Параметр поддерживает импорт викиданных. Есть возможность [[ВП:ЛЖЕГЕРБ|выключить]], заполнив параметр текстом <code>novalue</code>. Для полного выключения полосы надо так же заполнить параметр ''Герб''.
* ''описание_флага'' — Если не задано, по умолчанию отображается подпись Флаг. Подпись особенно полезна, если государство в разное время имело разл. флаги.
* ''Герб'' — герб территории. Параметр поддерживает импорт викиданных. Есть возможность [[ВП:ЛЖЕГЕРБ|выключить]], заполнив параметр текстом <code>novalue</code>. Для полного выключения полосы надо так же заполнить параметр ''Флаг''.
* ''описание_герба'' — Если не задано, по умолчанию отображается подпись Герб. Подпись особенно полезна, если государство в разное время имело разл. гербы.
* ''Карта'' — карта территории, желательно, по наиболее позднему состоянию. Параметр поддерживает импорт викиданных.
* ''размер'' — необязательное поле, по умолчанию = 270px
* ''Описание'' — описание карты, заметки.
* ''Девиз'' — девиз правящего дома либо государства.
* ''type_before'' — если этот параметр присутствует в шаблоне, то необходимо указать примерно следующее: «Государства-основатели», иначе удалите его, автоматически будет указано: «Предшественники».
* ''p1'' — название административной единицы, существовавшей на данной территории до создания предмета статьи (станет ссылкой).
* ''flag_p1'' — флаг административной единицы, существовавшей на данной территории до создания предмета статьи.
* ''image_pN '' — гербы и другие изображения, для которых нежелательна рамка (в формате <nowiki>[[File:...|Npx]]</nowiki>)
* ''s1'' — название административной единицы, существовавшей на данной территории после упразднения предмета статьи (станет ссылкой).
* ''flag_s1'' — флаг административной единицы, существовавшей на данной территории после упразднения предмета статьи.
* ''image_sN '' — гербы и другие изображения, для которых нежелательна рамка (в формате <nowiki>[[File:...|Npx]]</nowiki>)
* ''pN'' — другие предшественники (если более четырёх, используйте параметры «До» и «После»).
* ''flag_sN'' — флаги государств-предшественников.
* ''Образовано'' — год образования административной единицы. Параметр поддерживает импорт викиданных.
* ''ликвидировано'' — год прекращения существования административной единицы. Параметр поддерживает импорт викиданных.
* ''type_after'' — если этот параметр присутствует в шаблоне, то необходимо указать примерно следующее: «Государства после распада…», иначе удалите его, автоматически будет указано: «Преемники».
* ''pN'' — другие преемники (если более четырёх, используйте параметры «До» и «После»).
* ''flag_pN'' — флаги государств-преемников.
* ''Столица'' — административный центр территории. Параметр поддерживает импорт викиданных.
* ''Валюта'' — денежная единица данной территории. Параметр поддерживает импорт викиданных.
* ''Города'' — крупнейшие города данной территории.
* ''Язык'' — официальный язык территории. Параметр поддерживает импорт викиданных.
* ''Форма_правления'' — форма правления на данной территории. Параметр поддерживает импорт викиданных.
* ''титул_правителей'' — титулы правителей, заданных в параметрах правитель N. Например: «Короли». Если правители имели различные титулы, можно воспользоваться более общей формулировкой, например: «Основные правители».
* ''титул_правителейN'' — используется при изменении титула последующего правителя.
* ''правительN'' — имя правителя N
* ''год_правителяN'' — годы правления правителя N
* ''Дополнительный_параметр1, 2'' — название параметра.
* ''Содержимое_параметра1, 2'' — содержимое параметра.
* ''ЭтапN'' — название этапа в истории государства (до 11).
* ''ДатаN'' — дата начала этапа (до 11).
* ''ГодN'' — год начала этапа (до 11).
* ''До'' — название административной единицы, существовавшей на данной территории до создания предмета статьи.
* ''После'' — название административной единицы, существовавшей на данной территории после упразднения предмета статьи.
* ''дN'' — другие предшественники (до 7).
* ''пN'' — другие преемники (до 7).
* ''прим'' — примечания.
* ''викисклад'' — категория на Викискладе.
<includeonly>
[[Категория:Шаблоны-карточки:Географические объекты]]
[[Категория:Шаблоны-карточки:История]]
</includeonly>
56637e0862b3c305ebd1643f0787f74a89bf78cf
Шаблон:Ambox
10
193
433
432
2024-08-10T17:14:58Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{#invoke:Message box|ambox}}{{#ifeq:{{{small}}}|left|[[Категория:Страницы, использующие малые шаблоны-сообщения]]}}<noinclude>
{{doc}}
<!-- Categories go on the /doc subpage, and interwikis go on Wikidata. -->
</noinclude>
5345bd7c0e2430e3672a54d920abd0f0bf61dc61
Шаблон:TOC right
10
194
435
434
2024-08-10T17:15:04Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<templatestyles src="Шаблон:TOC right/styles.css" /><!--
-->{{#if: {{{limit|}}} | <templatestyles src="Шаблон:TOC limit/styles.css" /> }}<!--
--><div class="ts-TOC_right {{#if: {{{limit|}}} | ts-TOC_limit-{{{limit|}}} }}" style="{{#if: {{{clear|}}}
| clear:{{{clear|}}};
}}{{#if: {{{width|{{{1|}}}}}}
| width:{{{width|{{{1|}}}}}};
}}{{#if: {{{max-width|}}}
| max-width: {{{max-width|}}};
}}">__TOC__</div><noinclude>
{{doc}}
</noinclude>
84311f23c6ae2f952b4496c710868089ed317e45
Шаблон:TOC right/styles.css
10
195
437
436
2024-08-10T17:15:05Z
DuOfOrl
5
1 версия импортирована
sanitized-css
text/css
@media (min-width: 720px) {
body:not(.skin-minerva) .ts-TOC_right {
margin-left: 1em;
margin-bottom: 0.5em;
float: right;
clear: right;
}
}
@media (max-width: 719px) {
.ts-TOC_right {
width: auto !important;
max-width: none !important;
clear: none !important;
}
}
body.skin-vector-2022 .ts-TOC_right {
display: none;
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
710a99f2d4d2a78eb7a6f884538055bb6ac67c99
Шаблон:Начало скрытого блока
10
196
439
438
2024-08-10T17:15:06Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly><templatestyles src="Шаблон:Скрытый блок/styles.css" /><!--
--><div class="mw-collapsible {{#switch: {{{состояние|{{{state|}}}}}} | expanded | autocollapse = {{{состояние|{{{state|}}}}}} | mw-collapsed }} ts-Скрытый_блок ts-Скрытый_блок-{{#switch: {{{тип|{{{type|}}}}}} | gray | transparent = {{{тип|{{{type|}}}}}} | gray }} ts-Скрытый_блок-{{#switch: {{{Ссылка|{{{ссылка|}}}}}} | none = none | right | left = {{{Ссылка|{{{ссылка|}}}}}} | right }}HideLink {{{класс_тела|{{{класс тела|}}}}}}" style="{{ifempty |до = border: | {{{Рамка|{{{border|{{{рамка|}}}}}}}}} |после=;}}{{{frame-style|{{{стиль_тела|{{{стиль тела|}}}}}}}}}"><!--
--><div class="ts-Скрытый_блок-title {{#switch: {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}} | none = none | left | right = ts-Скрытый_блок-title-{{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}}Title }} {{{класс_заголовка|{{{класс заголовка|}}}}}}" style="<!--
-->{{ifempty |до = background-color: | {{{Фон_заголовка|{{{bg1|{{{фон_заголовка|{{{фон заголовка|}}}}}}}}}}}} |после=;}}<!--
-->{{ifempty |до = text-align: | {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}} |после=;}}<!--
-->{{ifempty |до = font-weight: | {{{Шрифт_заголовка|{{{шрифт_заголовка|{{{шрифт заголовка|}}}}}}}}} |после=;}}<!--
-->{{ifempty |до = font-style: | {{{Наклон_заголовка|{{{наклон_заголовка|{{{наклон заголовка|}}}}}}}}} |после=;}}<!--
-->{{{Стиль_заголовка|{{{extra1|{{{стиль_заголовка|{{{стиль заголовка|}}}}}}}}}}}}"><!--
-->{{{Заголовок|{{{заголовок|{{{Заглавие|{{{заглавие|{{{Название|{{{название|{{{header|{{{title|{{{1}}}}}}}}}}}}}}}}}}}}}}}}}}}<!--
--><div class="mw-collapsible-toggle-placeholder"></div></div><!--
--><div class="mw-collapsible-content {{{класс_текста|{{{класс текста|}}}}}}" style="<!--
-->{{ifempty |до = background-color: | {{{Фон_текста|{{{bg2|{{{фон_текста|{{{фон текста|}}}}}}}}}}}} |после=;}}<!--
-->{{ifempty |до = font-weight: | {{{Шрифт_текста|{{{шрифт_текста|{{{шрифт текста|}}}}}}}}} |после=;}}<!--
-->{{ifempty |до = font-style: | {{{Наклон_текста|{{{наклон_текста|{{{наклон текста|}}}}}}}}} |после=;}}<!--
-->{{ifempty |до = text-align: | {{{Выравнивание_текста|{{{ta2|{{{выравнивание_текста|{{{выравнивание текста|}}}}}}}}}}}} |после=;}}<!--
-->{{{Стиль_текста|{{{extra2|{{{стиль_текста|{{{стиль текста|}}}}}}}}}}}}"><!--
--></includeonly><noinclude>
{{doc}}
</noinclude>
3b96bb802b522e629c41cddc5d44dfb2a9eb462a
Шаблон:Скрытый блок/styles.css
10
197
441
440
2024-08-10T17:15:07Z
DuOfOrl
5
1 версия импортирована
sanitized-css
text/css
.ts-Скрытый_блок {
margin: 0;
overflow: hidden;
border-collapse: collapse;
box-sizing: border-box;
font-size: 95%;
}
.ts-Скрытый_блок-title {
text-align: center;
font-weight: bold;
line-height: 1.6em;
min-height: 1.2em;
}
.ts-Скрытый_блок .mw-collapsible-content {
overflow-x: auto;
overflow-y: hidden;
clear: both;
}
.ts-Скрытый_блок::before,
.ts-Скрытый_блок .mw-collapsible-toggle {
padding-top: .1em;
width: 6em;
font-weight: normal;
font-size: calc(90% / 0.95);
}
.ts-Скрытый_блок-rightHideLink .mw-collapsible-toggle {
float: right;
text-align: right;
}
.ts-Скрытый_блок-leftHideLink .mw-collapsible-toggle {
float: left;
text-align: left;
}
.ts-Скрытый_блок-gray {
padding: 2px;
border: 1px solid var(--border-color-base, #a2a9b1);
}
.ts-Скрытый_блок-transparent {
border: none;
}
.ts-Скрытый_блок-gray .ts-Скрытый_блок-title {
background: var(--background-color-neutral, #eaecf0);
padding: .1em 6em;
padding-right: 0;
}
.ts-Скрытый_блок-transparent .ts-Скрытый_блок-title {
background: transparent;
padding: .1em 5.5em;
padding-right: 0;
}
.ts-Скрытый_блок-gray .mw-collapsible-content {
padding: .25em 1em;
}
.ts-Скрытый_блок-transparent .mw-collapsible-content {
padding: .25em 0;
}
.ts-Скрытый_блок-gray.ts-Скрытый_блок-rightHideLink .mw-collapsible-toggle {
padding-right: 1em;
}
.ts-Скрытый_блок-transparent.ts-Скрытый_блок-rightHideLink .mw-collapsible-toggle {
padding-right: 0;
}
.ts-Скрытый_блок-gray.ts-Скрытый_блок-leftHideLink .mw-collapsible-toggle {
padding-left: 1em;
}
.ts-Скрытый_блок-transparent.ts-Скрытый_блок-leftHideLink .mw-collapsible-toggle {
padding-left: 0;
}
.ts-Скрытый_блок-gray.ts-Скрытый_блок-rightHideLink .ts-Скрытый_блок-title-leftTitle {
padding-left: 1em;
}
.ts-Скрытый_блок-gray.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-leftTitle {
padding-left: 6.5em;
}
.ts-Скрытый_блок-gray.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-rightTitle {
padding-right: 1em;
}
.ts-Скрытый_блок-transparent.ts-Скрытый_блок-rightHideLink .ts-Скрытый_блок-title-rightTitle,
.ts-Скрытый_блок-transparent.ts-Скрытый_блок-rightHideLink .ts-Скрытый_блок-title-leftTitle {
padding-left: 0;
}
.ts-Скрытый_блок-transparent.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-rightTitle,
.ts-Скрытый_блок-transparent.ts-Скрытый_блок-leftHideLink .ts-Скрытый_блок-title-leftTitle {
padding-right: 0;
}
.ts-Скрытый_блок + .ts-Скрытый_блок,
.ts-Скрытый_блок + link + .ts-Скрытый_блок {
border-top-style: hidden;
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
41e605b205f412804b46a4c6c5dd51a71c6a59ca
Шаблон:Ifempty
10
198
443
442
2024-08-10T17:15:07Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{#invoke:Ifempty|main}}</includeonly><noinclude>
{{Doc}}
<!-- Add categories and interwikis to the /doc subpage, not here!
Добавляйте категории и интервики на подстраницу документации, а не сюда -->
</noinclude>
c14bef2160201468f96da309e565ff2fde725cf5
Шаблон:Конец скрытого блока
10
199
445
444
2024-08-10T17:15:08Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly></div></div></includeonly><noinclude>
{{doc|Шаблон:Начало скрытого блока/doc}}</noinclude>
2da6ac8eb0812fb4183a70b516009d40920e281f
Шаблон:Скрытый блок
10
200
447
446
2024-08-10T17:15:10Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{Начало скрытого блока
|id = {{{id|}}}
|тип = {{{тип|{{{type|}}}}}}
|состояние = {{{state|{{{состояние|collapsed}}}}}}
|класс_тела = {{{класс_тела|{{{класс тела|}}}}}}
|стиль_тела = {{{frame-style|{{{стиль_тела|{{{стиль тела|}}}}}}}}}
|рамка = {{{Рамка|{{{border|{{{рамка|}}}}}}}}}
|заголовок = {{{Заголовок|{{{заголовок|{{{Заглавие|{{{заглавие|{{{Название|{{{название|{{{header|{{{title|{{{1}}}}}}}}}}}}}}}}}}}}}}}}}}}
|ссылка = {{{Ссылка|{{{ссылка|}}}}}}
|класс_заголовка = {{{класс_заголовка|{{{класс заголовка|}}}}}}
|шрифт_заголовка = {{{Шрифт_заголовка|{{{шрифт_заголовка|{{{шрифт заголовка|}}}}}}}}}
|наклон_заголовка = {{{Наклон_заголовка|{{{наклон_заголовка|{{{наклон заголовка|}}}}}}}}}
|фон_заголовка = {{{Фон_заголовка|{{{bg1|{{{фон_заголовка|{{{фон заголовка|}}}}}}}}}}}}
|выравнивание_заголовка = {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}}
|стиль_заголовка = {{{title-style|{{{Стиль_заголовка|{{{extra1|{{{стиль_заголовка|{{{стиль заголовка|}}}}}}}}}}}}}}}
|класс_текста = {{{класс_текста|{{{класс текста|}}}}}}
|шрифт_текста = {{{Шрифт_текста|{{{шрифт_текста|{{{шрифт текста|}}}}}}}}}
|наклон_текста = {{{Наклон_текста|{{{наклон_текста|{{{наклон текста|}}}}}}}}}
|фон_текста = {{{Фон_текста|{{{bg2|{{{фон_текста|{{{фон текста|}}}}}}}}}}}}
|выравнивание_текста = {{{Выравнивание_текста|{{{ta2|{{{выравнивание_текста|{{{выравнивание текста|}}}}}}}}}}}}
|стиль_текста = {{{content-style|{{{Стиль_текста|{{{extra2|{{{стиль_текста|{{{стиль текста|}}}}}}}}}}}}}}}}}
{{{content|{{{Содержание|{{{содержание|{{{2}}}}}}}}}}}}
{{#if: {{{footer|}}} | <div style="{{{footer-style|{{{title-style|}}}}}}">{{{footer}}}</div> }}
{{Конец скрытого блока}}<noinclude>
{{doc}}
</noinclude>
792dc9fb2eb659877e2e758f4ce405e1d3f8352b
Шаблон:Заготовка раздела
10
201
449
448
2024-08-10T17:15:11Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{ {{{|safesubst:}}}#invoke:Unsubst||дата=__DATE__|$format=Y-m-d|$B=
<!--{{Заготовка раздела}} begin-->{{ambox
| name = Заготовка раздела
| subst = <includeonly>{{subst:substcheck}}</includeonly>
| type = content
|image = [[Файл:Wiki letter w.svg|25px|link=|alt=]]
| issue = Этот раздел '''[[Википедия:Заготовка статьи|не завершён]]'''.
| talk = {{{talk|{{{обс|}}}}}}
| fix = Вы поможете проекту, [[Википедия:Правила и указания|исправив и дополнив]] его{{#if: {{{1|}}} | <nowiki /> следующей информацией: {{{1}}} }}.<br>{{{comment|{{{c|{{{комм|{{{ком|{{{комментарий|{{{к|{{{com|{{{comm|}}}}}}}}}}}}}}}}}}}}}}}}
| date = {{{date|{{{дата|}}}}}}
| all = Википедия:Статьи с незавершёнными разделами
| all2 = Википедия:Статьи с шаблонами недостатков по алфавиту
| nocat = {{{nocat|}}}
}}
}}<noinclude>{{doc}}</noinclude>
354fe71955c1f4efa21d425cae329d66f9b43ce6
Шаблон:Ok
10
202
451
450
2024-08-10T17:15:13Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
[[File:Yes check.svg|15px|link=|alt=✔]]<noinclude>
<!--alt нужен чтобы скрин-ридеры читали в атрибуте alt "✓" как "отметка" и чтобы без загрузки картинок показывалось "✓".
Без рамки "|мини" и с отключающим "|link=" подпись преобразовывается сайтом в два атрибута у img (alt и title), поэтому нужно сделать alt отдельно от title
"File" вместо "Файл" немного уменьшает размер включений шаблонов.-->
{{doc}}
</noinclude>
43161c9f08276343b6f3c9223a73c712bd7db413
Шаблон:Скрытый
10
203
453
452
2024-08-10T17:15:13Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
#перенаправление [[Шаблон:Скрытый блок]]
97cc939c1c8ece875b2ec360f85980bd6f1bbed7
Шаблон:Module rating
10
94
455
160
2024-08-10T17:15:14Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
#REDIRECT [[Шаблон:Рейтинг модуля]]
4fffdbbfc33a362b03306003030f85ea1a516c19
Шаблон:Tick
10
204
457
456
2024-08-10T17:15:15Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
#перенаправление [[Шаблон:Ok]]
f0887beb67bfbdc74fa97e8dd35f78474edfcefc
Шаблон:Cross
10
205
459
458
2024-08-10T17:15:16Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
[[File:X mark.svg|{{{1|20}}}px|link=|alt=]]<span style="display:none">N</span><!--template:cross--><noinclude>
{{documentation}}
</noinclude>
ed4b409e99cfe41368cc2f86462c7f46372ac8bb
Модуль:UnitTests
828
206
461
460
2024-08-10T17:15:17Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
-- Модуль основан на коде модуля [[:en:Module:UnitTests|Module:UnitTests]] англоязычного раздела Википедии.
-- UnitTester provides unit testing for other Lua scripts. For details see [[Wikipedia:Lua#Unit_testing]].
-- For user documentation see talk page.
local UnitTester = {}
local frame, tick, cross, should_highlight
local result_table_header = '{|class="wikitable unit-tests-result"\n|+ %s\n' ..
'! scope="col" | \n' ..
'! scope="col" | Тест\n' ..
'! scope="col" | Ожидаемое значение\n' ..
'! scope="col" | Фактическое значение '
local result_table_live_sandbox_header = '{|class="wikitable unit-tests-result"\n|+ %s\n' ..
'! scope="col" | \n' ..
'! scope="col" | Тест\n' ..
'! scope="col" | Фактическое значение\n' ..
'! scope="col" | Песочница\n' ..
'! scope="col" | Ожидаемое значение'
local result_table = { n = 0 }
local result_table_mt = {
insert = function (self, ...)
local n = self.n
for i = 1, select('#', ...) do
local val = select(i, ...)
if val ~= nil then
n = n + 1
self[n] = val
end
end
self.n = n
end,
insert_format = function (self, ...)
self:insert(string.format(...))
end,
concat = table.concat
}
result_table_mt.__index = result_table_mt
setmetatable(result_table, result_table_mt)
local num_failures = 0
local num_runs = 0
local function first_difference(s1, s2)
s1, s2 = tostring(s1), tostring(s2)
if s1 == s2 then return '' end
local max = math.min(#s1, #s2)
for i = 1, max do
if s1:sub(i,i) ~= s2:sub(i,i) then return i end
end
return max + 1
end
local function return_varargs(...)
return ...
end
function UnitTester:calculate_output(text, expected, actual, options)
-- Set up some variables for throughout for ease
num_runs = num_runs + 1
local options = options or {}
-- Fix any stripmarkers if asked to do so to prevent incorrect fails
local compared_expected = expected
local compared_actual = actual
if options.templatestyles then
local pattern = '(\127[^\127]*UNIQ%-%-templatestyles%-)(%x+)(%-QINU[^\127]*\127)'
local _, expected_stripmarker_id = compared_expected:match(pattern) -- when module rendering has templatestyles strip markers, use ID from expected to prevent false test fail
if expected_stripmarker_id then
compared_actual = compared_actual:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3') -- replace actual id with expected id; ignore second capture in pattern
compared_expected = compared_expected:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3') -- account for other strip markers
end
end
if options.stripmarker then
local pattern = '(\127[^\127]*UNIQ%-%-%l+%-)(%x+)(%-%-?QINU[^\127]*\127)'
local _, expected_stripmarker_id = compared_expected:match(pattern)
if expected_stripmarker_id then
compared_actual = compared_actual:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3')
compared_expected = compared_expected:gsub(pattern, '%1' .. expected_stripmarker_id .. '%3')
end
end
-- Perform the comparison
local success = compared_actual == compared_expected
if not success then
num_failures = num_failures + 1
end
-- Sort the wikitext for displaying the results
if options.combined then
-- We need 2 rows available for the expected and actual columns
-- Top one is parsed, bottom is unparsed
local differs_at = self.differs_at and (' \n| rowspan=2|' .. first_difference(compared_expected, compared_actual)) or ''
-- Local copies of tick/cross to allow for highlighting
local highlight = (should_highlight and not success and 'style="background:#fc0;" ') or ''
result_table:insert( -- Start output
'| ', highlight, 'rowspan=2|', success and tick or cross, -- Tick/Cross (2 rows)
' \n| rowspan=2|', mw.text.nowiki(text), ' \n| ', -- Text used for the test (2 rows)
expected, ' \n| ', actual, -- The parsed outputs (in the 1st row)
differs_at, ' \n|-\n| ', -- Where any relevant difference was (2 rows)
mw.text.nowiki(expected), ' \n| ', mw.text.nowiki(actual), -- The unparsed outputs (in the 2nd row)
'\n|-\n' -- End output
)
else
-- Display normally with whichever option was preferred (nowiki/parsed)
local differs_at = self.differs_at and (' \n| ' .. first_difference(compared_expected, compared_actual)) or ''
local formatting = options.nowiki and mw.text.nowiki or return_varargs
local highlight = (should_highlight and not success and 'style="background:#fc0;"|') or ''
result_table:insert( -- Start output
'| ', highlight, success and tick or cross, -- Tick/Cross
' \n| ', mw.text.nowiki(text), ' \n| ', -- Text used for the test
formatting(expected), ' \n| ', formatting(actual), -- The formatted outputs
differs_at, -- Where any relevant difference was
'\n|-\n' -- End output
)
end
end
function UnitTester:preprocess_equals(text, expected, options)
local actual = frame:preprocess(text)
self:calculate_output(text, expected, actual, options)
end
function UnitTester:preprocess_equals_many(prefix, suffix, cases, options)
for _, case in ipairs(cases) do
self:preprocess_equals(prefix .. case[1] .. suffix, case[2], options)
end
end
function UnitTester:preprocess_equals_preprocess(text1, text2, options)
local actual = frame:preprocess(text1)
local expected = frame:preprocess(text2)
self:calculate_output(text1, expected, actual, options)
end
function UnitTester:preprocess_equals_compare(live, sandbox, expected, options)
local live_text = frame:preprocess(live)
local sandbox_text = frame:preprocess(sandbox)
local highlight_live = false
local highlight_sandbox = false
num_runs = num_runs + 1
if live_text == expected and sandbox_text == expected then
result_table:insert('| ', tick)
else
result_table:insert('| ', cross)
num_failures = num_failures + 1
if live_text ~= expected then
highlight_live = true
end
if sandbox_text ~= expected then
highlight_sandbox = true
end
end
local formatting = (options and options.nowiki and mw.text.nowiki) or return_varargs
local differs_at = self.differs_at and (' \n| ' .. first_difference(expected, live_text) or first_difference(expected, sandbox_text)) or ''
result_table:insert(
' \n| ',
mw.text.nowiki(live),
should_highlight and highlight_live and ' \n|style="background: #fc0;"| ' or ' \n| ',
formatting(live_text),
should_highlight and highlight_sandbox and ' \n|style="background: #fc0;"| ' or ' \n| ',
formatting(sandbox_text),
' \n| ',
formatting(expected),
differs_at,
"\n|-\n"
)
end
function UnitTester:preprocess_equals_preprocess_many(prefix1, suffix1, prefix2, suffix2, cases, options)
for _, case in ipairs(cases) do
self:preprocess_equals_preprocess(prefix1 .. case[1] .. suffix1, prefix2 .. (case[2] and case[2] or case[1]) .. suffix2, options)
end
end
function UnitTester:preprocess_equals_sandbox_many(module, function_name, cases, options)
for _, case in ipairs(cases) do
local live = module .. "|" .. function_name .. "|" .. case[1] .. "}}"
local sandbox = module .. "/песочница|" .. function_name .. "|" .. case[1] .. "}}"
self:preprocess_equals_compare(live, sandbox, case[2], options)
end
end
function UnitTester:equals(name, actual, expected, options)
num_runs = num_runs + 1
if actual == expected then
result_table:insert('| ', tick)
else
result_table:insert('| ', cross)
num_failures = num_failures + 1
end
local formatting = (options and options.nowiki and mw.text.nowiki) or return_varargs
local differs_at = self.differs_at and (' \n| ' .. first_difference(expected, actual)) or ''
local display = options and options.display or return_varargs
result_table:insert(' \n| ', name, ' \n| ',
formatting(tostring(display(expected))), ' \n| ',
formatting(tostring(display(actual))), differs_at, "\n|-\n")
end
local function deep_compare(t1, t2, ignore_mt)
local ty1 = type(t1)
local ty2 = type(t2)
if ty1 ~= ty2 then return false end
if ty1 ~= 'table' and ty2 ~= 'table' then return t1 == t2 end
local mt = getmetatable(t1)
if not ignore_mt and mt and mt.__eq then return t1 == t2 end
for k1, v1 in pairs(t1) do
local v2 = t2[k1]
if v2 == nil or not deep_compare(v1, v2) then return false end
end
for k2, v2 in pairs(t2) do
local v1 = t1[k2]
if v1 == nil or not deep_compare(v1, v2) then return false end
end
return true
end
local function val_to_str(obj)
local function table_key_to_str(k)
if type(k) == 'string' and mw.ustring.match(k, '^[_%a][_%a%d]*$') then
return k
else
return '[' .. val_to_str(k) .. ']'
end
end
if type(obj) == "string" then
obj = mw.ustring.gsub(obj, "\n", "\\n")
if mw.ustring.match(mw.ustring.gsub(obj, '[^\'"]', ''), '^"+$') then
return "'" .. obj .. "'"
end
return '"' .. mw.ustring.gsub(obj, '"', '\\"' ) .. '"'
elseif type(obj) == "table" then
local result, checked = {}, {}
for k, v in ipairs(obj) do
table.insert(result, val_to_str(v))
checked[k] = true
end
for k, v in pairs(obj) do
if not checked[k] then
table.insert(result, table_key_to_str(k) .. '=' .. val_to_str(v))
end
end
return '{' .. table.concat(result, ',') .. '}'
else
return tostring(obj)
end
end
function UnitTester:equals_deep(name, actual, expected, options)
num_runs = num_runs + 1
if deep_compare(actual, expected) then
result_table:insert('| ', tick)
else
result_table:insert('| ', cross)
num_failures = num_failures + 1
end
local formatting = (options and options.nowiki and mw.text.nowiki) or return_varargs
local actual_str = val_to_str(actual)
local expected_str = val_to_str(expected)
local differs_at = self.differs_at and (' \n| ' .. first_difference(expected_str, actual_str)) or ''
result_table:insert(' \n| ', name, ' \n| ', formatting(expected_str),
' \n| ', formatting(actual_str), differs_at, "\n|-\n")
end
function UnitTester:iterate(examples, func)
require 'libraryUtil'.checkType('iterate', 1, examples, 'table')
if type(func) == 'string' then
func = self[func]
elseif type(func) ~= 'function' then
error(("bad argument #2 to 'iterate' (expected function or string, got %s)")
:format(type(func)), 2)
end
for i, example in ipairs(examples) do
if type(example) == 'table' then
func(self, unpack(example))
elseif type(example) == 'string' then
self:heading(example)
else
error(('bad example #%d (expected table, got %s)')
:format(i, type(example)), 2)
end
end
end
function UnitTester:heading(text)
result_table:insert_format(' ! colspan="%u" style="text-align: left" | %s \n |- \n ',
self.columns, text)
end
function UnitTester:run(frame_arg)
frame = frame_arg
self.frame = frame
self.differs_at = frame.args['differs_at']
tick = frame:preprocess('{{Tick}}')
cross = frame:preprocess('{{Cross}}')
local table_header = result_table_header
if frame.args['live_sandbox'] then
table_header = result_table_live_sandbox_header
end
if frame.args.highlight then
should_highlight = true
end
self.columns = 4
if self.differs_at then
table_header = table_header .. '\n! scope="col" title="Различается на символе" | Разл. на'
self.columns = self.columns + 1
end
-- Sort results into alphabetical order.
local self_sorted = {}
for key, _ in pairs(self) do
if key:find('^test') then
table.insert(self_sorted, key)
end
end
table.sort(self_sorted)
-- Add results to the results table.
for _, value in ipairs(self_sorted) do
result_table:insert_format(table_header .. "\n|-\n", value)
self[value](self)
result_table:insert("|}\n")
end
local cat_failures = '[[Категория:Модули:Страницы с проваленными юнит-тестами]]'
return (num_runs == 0 and "<b>Нет тестов для запуска.</b>"
or num_failures == 0 and "<b style=\"color:#008000\">Все тесты успешно пройдены: " .. num_runs .. "</b>"
or "<b style=\"color:#800000\">" .. num_failures .. " тестов из " .. num_runs .. " провалено.</b>" .. cat_failures
) .. "\n\n" .. frame:preprocess(result_table:concat())
end
function UnitTester:new()
local o = {}
setmetatable(o, self)
self.__index = self
return o
end
local p = UnitTester:new()
function p.run_tests(frame) return p:run(frame) end
return p
f88824c8866c120062332f00624435f8323f488b
Шаблон:СИШ
10
207
463
462
2024-08-10T17:15:17Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<noinclude>{{к объединению|2020-11-10|Шаблон:High-use}}
</noinclude>{{ombox
|type = notice
|image = [[Файл:Stalewarning.svg|40px|alt=Время]]
|text = '''Внимание! Это один из [[Special:MostLinkedTemplates|самых используемых {{#ifeq: {{NAMESPACENUMBER}} | 828 | модулей | шаблонов }}]].'''
|text-small = Каждое его изменение создаёт [[mw:Manual:Job queue/ru|дополнительную нагрузку]] на сервера проекта. Пожалуйста, убедитесь в адекватности и правильности ваших изменений, проверьте их на тестовых страницах.<br>[https://templatecount.toolforge.org/index.php?lang=ru&name={{PAGENAMEE}}&namespace={{NAMESPACENUMBER}} Узнать число включений].
}}<includeonly>{{no-doc|nocat={{{nocat|}}}|[[Категория:Шаблоны:С более чем 100 тысячами использований]]}}</includeonly><noinclude>
{{doc}}
</noinclude>
013201ef8d4ba8e3d1eb0dbba9c331a3d4ae519b
Модуль:Wikidata/doc
828
208
465
464
2024-08-10T17:15:18Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{СИШ}}
{{module rating|p}}
{{TOC right}}
Используется в {{tl|Wikidata}} (см. описания параметров там же). Настраивается при помощи [[Модуль:Wikidata/config]].
Прежде чем вносить какие-либо изменения в данный модуль, просьба оттестировать их в [[Модуль:Wikidata/песочница|/песочнице]]. Обратите внимание, что не всё корректно работает в песочнице.
== Общие сведения ==
Функции данного модуля не предназначены для прямого вызова из шаблонов карточек или других модулей, не являющихся функциями расширения данного. Для вызова из шаблонов карточек используйте шаблон {{tl|wikidata}} или один из специализированных шаблонов для свойств. Для вызова функций Викиданных предназначенных для отображения чаще всего достаточно вызова <code>frame:expandTemplate{}</code> с вызовом шаблона, ответственного за отрисовку свойства. С другой стороны, вызов определённых функций модуля (в основном это касается <code>getEntity()</code>) может в будущем стать предпочтительным. Данный Lua-функционал в любом случае стоит рассматривать как unstable с точки зрения сохранения совместимости на уровне кода (вместе с соответствующими функциями API для Wikibase Client).
Далее описывается внутренняя документация. Названия функций и параметров могут изменяться. При их изменении автор изменений обязан обновить шаблон {{tl|wikidata}} и специализированные шаблоны свойств. Изменения в других местах, если кто-то всё-таки вызывает функции модуля напрямую, остаются на совести автора «костыля». Итак, при вызове шаблона {{tl|wikidata}} или специализированного шаблона свойства управление отдаётся на функцию formatStatements, которая принимает frame. Из frame достаются следующие опции, которые так или иначе передаются в остальные функции:
* <code>plain</code> — булевый переключатель (по умолчанию false). Если true, результат совпадает с обычным вызовом <code><nowiki>{{#property:pNNN}}</nowiki></code> (по факту им и будет являться)
* <code>references</code> — булевый переключатель (по умолчанию true). Если true, после вывода значения параметра дополнительно выводит ссылки на источники, указанные в Викиданных. Для вывода используется [[Модуль:Sources]]. Обычно отключается для тех свойств, которые являются «самоописываемыми», например, внешними идентификаторами или ссылками (когда такая ссылка является доказательством своей актуальности), например, идентификаторы IMDb.
* <code>value</code> — значение, которое надо выводить ''вместо'' значений из Викиданных (используется, если что-то задано уже в карточке в виде т. н. локального свойства)
По умолчанию модуль поддерживает вывод следующих значений без дополнительных настроек:
* географические координаты (coordinates)
* количественные значения (quantity)
* моноязычный текст (monolingualtext)
* строки (string)
* даты (time)
Остальные типы данных требуют указания функции форматирования значения.
== Кастомизация ==
Поддерживаются три типа параметров-функций, которые дополнительно указывают, как надо форматировать значения:
* <code>property-module</code>, <code>property-function</code> — название модуля и функции модуля, которые отвечают за форматирование вывода массива значений ''свойства'' (property) с учётом квалификаторов, ссылок и прочего. Например, оформляет множество выводов в таблицу или график. Характерные примеры:
** вывод таблицы и графика населения в {{tl|wikidata/Population}} и [[Модуль:Wikidata/Population]].
*: Спецификация функции: <code>function p.…( context, options )</code>, поведение по умолчанию: [[Модуль:Wikidata#formatPropertyDefault]].
* <code>claim-module</code>, <code>claim-function</code> — название модуля и функции модуля, которые отвечают за форматирование вывода значения ''свойства'' (statement, claim) с учётом квалификаторов, ссылок и прочего. Может, например, дополнительно к основному значению (main snak) вывести значения квалификаторов. Характерные примеры:
** вывод вышестоящих административных единиц и страны в [[Модуль:Wikidata/Places]];
** вывод авторов латинского названия и даты публикации в [[Модуль:Wikidata/Biology]];
** вывод операционной системы и даты релиза в [[Модуль:Wikidata/Software]];
** вывод количества и даты, на которую оно верно, в [[Модуль:Wikidata/number]];
*: Спецификация функции: <code>function p.…( context, options, statement )</code>
* <code>value-module</code>, <code>value-function</code> — название модуля и функции модуля, которые отвечают за форматирование ''значения'' (snak, snak data value), в зависимости от контекста, как значений свойства, так и значений квалификатора (если вызывается из <code>claim-module/claim-function</code>). Необходимо для изменения отображения свойства, например, генерации викиссылки вместо простой строки или даже вставки изображения вместо отображения имени файла изображения (так как ссылки на изображения хранятся как строки). Характерные примеры:
** вывод ссылки на [[Викисклад]] в [[Модуль:Wikidata/media]]
** вывод ссылок на внешние сайты в [[Модуль:Wikidata/link]]
*: Спецификация функции: <code>function p.…( value, options )</code>
=== Заготовки функций ===
{{Скрытый
| Заголовок = property-function
| Содержание = <syntaxhighlight lang="lua">
function p.formatSomeProperty( context, options )
local claims = context.selectClaims( options, options.property );
if claims == nil then
return ''
end
local formattedStatements = {}
for _, claim in ipairs( claims ) do
local formattedStatement = context.formatStatement( options, claim )
-- local formattedStatement = p.formatSomeStatement( context, options, claim )
if ( formattedStatement and formattedStatement ~= '' ) then
formattedStatement = context.wrapStatement( formattedStatement, options.property, claim.id )
table.insert( formattedStatements, formattedStatement )
end
end
return mw.text.listToText( formattedStatements, options.separator, options.conjunction )
end
</syntaxhighlight>
Также см. код метода <code>formatPropertyDefault</code> ниже, в нём присутствует больше проверок и работа параметрами вызова.
}}
{{Скрытый
| Заголовок = claim-function
| Содержание = <syntaxhighlight lang="lua">
function formatSomeClaim( context, options, statement )
local circumstances = context.getSourcingCircumstances( statement );
options.qualifiers = statement.qualifiers;
local result = context.formatSnak( options, statement.mainsnak, circumstances );
if ( result and result ~= '' and options.references ) then
result = result .. context.formatRefs( options, statement );
end
return result;
end
</syntaxhighlight>
Также см. код метода <code>formatStatementDefault</code> ниже, в нём есть пример работы с квалификаторами.
}}
{{Скрытый
| Заголовок = value-function
| Содержание = <syntaxhighlight lang="lua">
function formatSomeValue( context, options, value )
return value;
end
</syntaxhighlight>
Также см. код метода <code>formatUrlSingle</code> в модуле [[Модуль:URL]].
}}
=== Context API ===
{{Заготовка раздела|описать публичные методы, доступные через <code>context</code>.}}
==== Переменные ====
* <code>entity</code>
* <code>frame</code>
==== Методы ====
* <code>cloneOptions( options )</code>
* <code>getSourcingCircumstances( statement )</code>
* <code>formatProperty( options )</code>
* <code>formatPropertyDefault( context, options )</code>
* <code>formatSnak( options, snak, circumstances )</code>
* <code>formatStatement( options, statement )</code>
* <code>formatStatementDefault( context, options, statement )</code>
* <code>formatRefs( options, statement )</code>
* <code>formatValueDefault( context, options, value )</code>
* <code>parseTimeBoundariesFromSnak( snak )</code>
* <code>parseTimeFromSnak( snak )</code>
* <code>selectClaims( options, propertyId )</code>
* <code>wrapSnak( value, hash, attributes )</code>
* <code>wrapStatement( value, propertyId, claimId, attributes )</code>
* <code>wrapQualifier( value, qualifierId, attributes )</code>
=== Функции для форматирования ===
==== property-function ====
* [[Модуль:Wikidata/date|Wikidata/date]]::formatDateIntervalProperty
* [[Модуль:Wikidata/Medals|Wikidata/Medals]]::formatProperty
* [[Модуль:Wikidata/Software|Wikidata/Software]]::formatVersionProperty
* [[Модуль:Wikidata/P512|Wikidata/P512]]::formatAcademicDegree
* [[Модуль:Wikidata/number|Wikidata/number]]::formatPropertyWithMostRecentClaimAndIndicator
* [[Модуль:Wikidata/number|Wikidata/number]]::formatColorIndex
==== claim-function ====
* [[Модуль:Wikidata/Places|Wikidata/Places]]::formatCountryClaimWithFlag
* [[Модуль:Wikidata/Places|Wikidata/Places]]::formatPlaceWithQualifiers
* [[Модуль:Wikidata/item|Wikidata/item]]::formatEntityWithGenderClaim
* [[Модуль:Wikidata/Biology|Wikidata/Biology]]::formatTaxonNameClaim
* [[Модуль:Wikidata/item|Wikidata/item]]::applyDefaultTemplate
* [[Модуль:Wikidata/date|Wikidata/date]]::formatDateOfBirthClaim
* [[Модуль:Wikidata/date|Wikidata/date]]::formatDateOfDeathClaim
==== value-function ====
* [[Модуль:Wikidata|Wikidata]]::extractCategory
* [[Модуль:Wikidata/link|Wikidata/link]]::fromModule
* [[Модуль:Wikidata/Medals|Wikidata/Medals]]::formatValue
* [[Модуль:Wikidata/media|Wikidata/media]]::formatCommonsCategory
* [[Модуль:Wikidata/Software|Wikidata/Software]]::formatExtension
* [[Модуль:Wikidata/number|Wikidata/number]]::formatRA
* [[Модуль:Wikidata/number|Wikidata/number]]::formatDMS
* [[Модуль:Wikidata/url|Wikidata/url]]::formatUrlValue
* [[Модуль:Wikidata/url|Wikidata/url]]::formatLangRefs
== Тесты ==
{{Скрытый
| Заголовок = [[Модуль:Wikidata/tests]]
| Содержание = {{#invoke:Wikidata/tests|run_tests}}
}}
== См. также ==
* [[Модуль:Wikibase]]
* Независимые иноязычные аналоги:
** [[:fr:Module:Wikidata]]
** [[:ca:Mòdul:Wikidades]]
** [[:it:Modulo:Wikidata]]
** [[:de:Modul:Wikidata]]
** [[:en:Module:WikidataIB]]
** [[:en:Module:Wd]]
<noinclude>
[[Категория:Модули:Документация]]
</noinclude>
<includeonly>
[[Категория:Модули:Викиданные]]
</includeonly>
1e00ff235ce39f7fd8e5927f57fda177a193a7a6
Модуль:Message box/ambox.css
828
209
467
466
2024-08-10T17:15:19Z
DuOfOrl
5
1 версия импортирована
sanitized-css
text/css
/* Скопировано из [[:en:Module:Message box/ambox.css]] с изменениями */
.ambox {
border: 1px solid var(--border-color-base, #a2a9b1);
/* @noflip */
border-left: 10px solid #36c; /* Default "notice" blue */
background: var(--background-color-neutral-subtle, #f8f9fa);
box-sizing: border-box;
margin: 0 10%;
}
/* Не ухудшаем стили для Минервы */
html body.mediawiki.skin-minerva .ambox {
border-width: 0 0 0 4px;
}
/* Single border between stacked boxes. Take into account base templatestyles,
* user styles, and Template:Dated maintenance category.
* remove link selector when T200206 is fixed
*/
.ambox + link + .ambox,
.ambox + link + style + .ambox,
.ambox + link + link + .ambox,
/* TODO: raise these as "is this really that necessary???". the change was Dec 2021 */
.ambox + .mw-empty-elt + link + .ambox,
.ambox + .mw-empty-elt + link + style + .ambox,
.ambox + .mw-empty-elt + link + link + .ambox {
margin-top: -1px;
}
/* For the "small=left" option. */
/* must override .ambox + .ambox styles above */
html body.mediawiki .ambox.mbox-small-left {
/* @noflip */
margin: 4px 1em 4px 0;
overflow: hidden;
width: 238px;
border-collapse: collapse;
font-size: 88%;
line-height: 1.25em;
}
.ambox-speedy {
/* @noflip */
border-left: 10px solid var(--border-color-error, #b32424); /* Red */
background-color: var(--background-color-error-subtle, #fee7e6); /* Pink */
}
.ambox-delete {
/* @noflip */
border-left: 10px solid var(--border-color-error, #b32424); /* Red */
}
.ambox-content {
/* @noflip */
border-left: 10px solid #f28500; /* Orange */
}
.ambox-style {
/* @noflip */
border-left: 10px solid var(--color-warning, #edab00); /* Yellow */
}
.ambox-good {
/* @noflip */
border-left: 10px solid #66cc44;
}
.ambox-discussion {
/* @noflip */
border-left: 10px solid #339966;
}
.ambox-merge {
/* @noflip */
border-left: 10px solid #9932cc;
}
.ambox-move {
/* @noflip */
border-left: 10px solid #9932cc; /* Purple */
}
.ambox-protection {
/* @noflip */
border-left: 10px solid #a2a9b1; /* Gray-gold */
}
.ambox .mbox-text {
border: none;
/* @noflip */
padding: 0.25em 0.5em;
width: 100%;
}
.ambox .mbox-image {
border: none;
/* @noflip */
padding: 2px 0 2px 0.5em;
text-align: center;
}
.ambox .mbox-imageright {
border: none;
/* @noflip */
padding: 2px 0.5em 2px 0;
text-align: center;
}
/* An empty narrow cell */
.ambox .mbox-empty-cell {
border: none;
padding: 0;
width: 1px;
}
.ambox .mbox-image-div {
width: 52px;
}
/* Хак, TODO: посмотреть, как оно на самом деле работает */
.ambox .mbox-textsmall-div {
font-size: 90%;
}
/* Hack around MobileFrontend being opinionated */
html.client-js body.skin-minerva .mbox-text-span {
margin-left: 23px !important;
}
/* Стили нотификаций для ноутбуков */
@media (max-width: 1366px) {
.ambox {
margin-left: 6%;
margin-right: 6%;
}
}
/* Стили нотификаций для мобильного устройсва */
@media (max-width: 719px) {
.ambox {
margin-left: 0;
margin-right: 0;
}
}
/* [[Категория:Модули:Подстраницы CSS]] */
1d03f5efb7ec589bb5edde009c3ae9ef13460e7e
Модуль:Wikidata/tests
828
210
469
468
2024-08-10T17:15:19Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
-- Unit tests for [[Module:URL]]. Click talk page to run tests.
local p = require( 'Module:UnitTests' )
local wd = require( 'Module:Wikidata' )
local getSnak = function( timeString )
return {
datatype = "time",
datavalue = {
type = "time",
value = {
after = 0,
before = 0,
calendarmodel = "http://www.wikidata.org/entity/Q1985727",
precision = 11,
time = timeString,
timezone = 0,
},
},
hash = "33bd9a339157ce7b3d74cb10d73bc23529c9a7f3",
property = "P585",
snaktype = "value",
}
end
function p:test_parseTimeBoundaries()
self:equals_deep( '2000-12-31', wd._parseTimeBoundaries( '+2000-12-31T00:00:00Z', 11 ), { 978220800000, 978307199999 } )
self:equals_deep( '2001-01-01', wd._parseTimeBoundaries( '+2001-01-01T00:00:00Z', 11 ), { 978307200000, 978393599999 } )
self:equals_deep( '2001', wd._parseTimeBoundaries( '+2001-00-00T00:00:00Z', 9 ), { 978307200000, 1009843199999 } )
end
function p:test_parseTimeFromSnak()
self:equals_deep( '2000-12-31', wd._parseTimeFromSnak( getSnak( '+2000-12-31T00:00:00Z' ) ), 978220800000 )
self:equals_deep( '2001-01-01', wd._parseTimeFromSnak( getSnak( '+2001-01-01T00:00:00Z' ) ), 978307200000 )
self:equals_deep( '2001', wd._parseTimeFromSnak( getSnak( '+2001-00-00T00:00:00Z' ) ), 978307200000 )
end
return p
a49c6e32801a352e27ec0dee7b1af3c93a0f5c10
Модуль:Infobox
828
211
471
470
2024-08-10T17:21:56Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
local p = {};
local yesno = require('Module:Yesno')
local function _renderLine( frame, args, i )
if args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] == '-' then
return ''
elseif args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] ~= '' then
local style = ( args[ 'стиль_заголовков' ] or '' ) .. ( args[ 'стиль_заголовка' .. i ] or '' );
local class = ( args[ 'класс' .. i ] or '' );
return '\n<tr>\n<th colspan="2" scope="colgroup" class="infobox-header ' .. class .. '" style="' .. style .. '">' ..
args[ 'заголовок' .. i ] ..
'</th>\n</tr>';
end
if args[ 'блок' .. i ] and args[ 'блок' .. i ] ~= '' then
return args[ 'блок' .. i ];
end
local text = args[ 'текст' .. i ] or '';
if args[ 'викиданные' .. i ] and args[ 'викиданные' .. i ] ~= '' then
text = frame:expandTemplate{ title = 'Wikidata', args = {
args[ 'викиданные' .. i ],
text,
from = args[ 'from' ] or ''
} };
end
if text ~= '' then
local label = args[ 'метка' .. i ] or '';
local class = args[ 'класс' .. i ] or '';
if string.find(class, 'noplainlist') == nil and string.find(class, 'nofirstlevel') == nil then
class = class .. ' plainlist';
end
if class ~= '' then
class = ' class="' .. class .. '"';
end
local style = ( args[ 'стиль_текстов' ] or '' ) .. ( args[ 'стиль_текста' ] or '' ) .. ( args[ 'стиль_текста' .. i ] or '' );
if label == '' then
style = 'text-align:center;' .. style;
end
if style ~= '' then
style = ' style="' .. style .. '"';
end
if label ~= '' then
local labelClass = args[ 'класс_меток' ] or '';
if string.find(labelClass, 'noplainlist') == nil and string.find(labelClass, 'nofirstlevel') == nil then
labelClass = labelClass .. ' plainlist';
end
if labelClass ~= '' then
labelClass = ' class="' .. labelClass .. '"';
end
local labelStyle = ( args[ 'стиль_меток' ] or '' ) .. ( args[ 'стиль_метки' .. i ] or '' );
if labelStyle ~= '' then
labelStyle = ' style="' .. labelStyle .. '"';
end
return '\n<tr>\n<th scope="row"' .. labelClass .. labelStyle .. '>' .. label .. '</th>' ..
'\n<td' .. class .. style .. '>\n' .. text .. '</td>\n</tr>';
end
return '\n<tr>\n<td colspan="2"' .. class .. style .. '>\n' .. text .. '</td>\n</tr>';
end
return '';
end
local function maxNumber ( args )
local maxNumber = 0
for argName, _ in pairs(args) do
local argNumber = mw.ustring.match(argName, '^[^0-9]+([0-9]+)$')
if argNumber and tonumber(argNumber) > maxNumber then
maxNumber = tonumber(argNumber)
end
end
return maxNumber
end
function p.renderLine( frame )
local args = frame:getParent().args;
return _renderLine(frame, args, '')
end
function p.renderLines( frame )
local args = frame:getParent().args;
local res = ''
local header, text = '', ''
local autoHeaders = yesno(args [ 'автозаголовки' ] or 'false', false)
for i = 1, maxNumber(args) do
if args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] ~= '' then
if text ~= '' or not autoHeaders then
res = res .. header .. text
end
header, text = _renderLine(frame, args, i), ''
else
text = text .. _renderLine(frame, args, i)
end
end
if text ~= '' or not autoHeaders then
res = res .. header .. text
end
return res
end
return p;
c830c997bd3d15923f347277e3b0ae71b7ba917e
Шаблон:Политик/doc
10
304
769
2024-08-15T11:45:35Z
ruwiki>A particle for world to form
0
?
wikitext
text/x-wiki
{{docpage}}
{{OnLua|CategoryForProfession}}
{{Установлена проверка на неизвестные параметры}}
{{Uses Wikidata|p18|p19|p20|p22|p25|p27|p40|p102|p106|p109|p140|p166|p512|p569|p570|p856|p1142|p1559}}
Этот [[Википедия:Шаблоны-карточки|шаблон-карточка]] предназначен для статей о политиках. Для государственных деятелей существует шаблон {{t|Государственный деятель}}.
Внимание, шаблон поддерживает загрузку дат смерти и рождения через [[ВП:Викиданные|Викиданные]]. Не заполняйте в шаблоне эти поля, если есть возможность использовать wikidata.
''Отметим, что большинство полей автоматически загружают информации из [[ВП:Викиданные|Викиданных]].''
Категории профессий по алфавиту и по странам добавляются автоматически на основе информации из викиданных. В случае если персоналию не следует добавлять в категорию, то существует параметр <code>без категорий=</code> в которым следует перечислить названия исключаемых категорий через точку с запятой. Пример использования — [[Special:Diff/70059213/70085957]].
Если есть только год рождения/смерти, так и пишите только цифры года.
{{Старый-новый стиль,примечание}}
== Заготовка для копирования ==
{{Заготовка шаблона}}
== Пример использования ==
{{Пример шаблона}}
== Отслеживающие категории ==
В служебных целях используется ряд скрытых отслеживающих категорий:
{{categorytree|Отслеживающие категории:Шаблон:Политик|категории|0|title=}}
== TemplateData ==
<templatedata>
{
"params": {
"nocat": {
"type": "boolean"
},
"from": {
"type": "line"
},
"имя": {
"aliases": [
"Имя"
],
"label": "имя",
"description": "имя персоны",
"type": "line",
"example": "Джон Доу"
},
"оригинал имени": {
"aliases": [
"Оригинал имени"
],
"label": "оригинал имени",
"description": "имя персоны на языке оригинала, обёрнутое в шаблон серии {{t|lang-en}}",
"example": "{{lang-en|John Doe}}",
"type": "string"
},
"изображение": {
"aliases": [
"Изображение"
],
"label": "изображение",
"description": "изображение персоны (P18)",
"example": "example.jpg",
"type": "wiki-file-name"
},
"ширина": {
"aliases": [
"Ширина"
],
"label": "ширина",
"type": "number",
"description": "размер изображения"
},
"описание изображения": {
"aliases": [
"Описание изображения"
],
"label": "описание изображения",
"description": "должно характеризовать портрет",
"type": "string"
},
"имя при рождении": {
"aliases": [
"Имя при рождении"
],
"label": "имя при рождении",
"description": "имя при рождении, если было изменено",
"type": "string"
},
"псевдонимы": {
"aliases": [
"Псевдонимы"
],
"label": "псевдонимы",
"type": "string"
},
"дата рождения": {
"aliases": [
"Дата рождения"
],
"label": "дата рождения",
"type": "date",
"description": "дд.мм.гггг (P569)",
"example": "02.01.1960"
},
"дата смерти": {
"aliases": [
"Дата смерти"
],
"label": "дата смерти",
"type": "date",
"description": "дд.мм.гггг (P570)",
"example": "02.01.2000"
},
"место рождения": {
"aliases": [
"Место рождения"
],
"label": "место рождения",
"description": "место рождения (P19)",
"type": "string",
"example": "{{МестоРождения|Лондон}}",
"autovalue": "{{МестоРождения|}}"
},
"место смерти": {
"aliases": [
"Место смерти"
],
"label": "место смерти",
"description": "место смерти (P20)",
"type": "string",
"example": "{{МестоСмерти|Москва}}",
"autovalue": "{{МестоСмерти|}}"
},
"гражданство": {
"aliases": [
"Гражданство",
"страна",
"подданство"
],
"label": "гражданство",
"description": "гражданство (P27)",
"type": "string",
"example": "[[Великобритания]], [[Россия]]"
},
"род деятельности": {
"aliases": [
"Род деятельности"
],
"label": "род деятельности",
"description": "род деятельности (P106)",
"type": "string",
"example": "[[политик]], [[журналист]], [[издатель]]"
},
"образование": {
"aliases": [
"Образование",
"альма-матер"
],
"label": "образование",
"description": "оконченное высшее учебное заведение (P69)",
"type": "string",
"example": "[[Московский государственный университет]]"
},
"учёная степень": {
"aliases": [
"Учёная степень"
],
"label": "учёная степень",
"type": "string",
"description": "учёная степень (P512)",
"example": "{{Учёная степень|доктор|экономических наук}}",
"autovalue": "{{Учёная степень||}}"
},
"вероисповедание": {
"aliases": [
"Вероисповедание"
],
"label": "вероисповедание",
"type": "string",
"description": "вероисповедание персоны",
"example": "[[католицизм]]"
},
"партия": {
"aliases": [
"Партия"
],
"label": "партия",
"type": "string",
"description": "партии и организации",
"example": "[[КПСС]], [[Партия любителей пива]]"
},
"основные идеи": {
"aliases": [
"Основные идеи"
],
"label": "основные идеи",
"type": "string",
"description": "политические взгляды и основные идеи (P1142)",
"example": "[[коммунизм]], [[национализм]]"
},
"отец": {
"aliases": [
"Отец"
],
"label": "отец",
"description": "отец (P22)",
"type": "string"
},
"мать": {
"aliases": [
"Мать"
],
"label": "мать",
"description": "мать (P25)",
"type": "string"
},
"супруг": {
"aliases": [
"Супруг"
],
"label": "супруг",
"description": "супруг (P26)",
"type": "string"
},
"супруга": {
"aliases": [
"Супруга"
],
"label": "супруга",
"description": "супруга (P26)",
"type": "string"
},
"дети": {
"aliases": [
"Дети"
],
"label": "дети",
"description": "дети (P40)",
"type": "string"
},
"награды": {
"aliases": [
"Награды",
"награды и премии"
],
"label": "награды",
"description": "ордена, медали и тому подобное; для них есть специальные шаблоны (P166)",
"type": "string",
"example": "{{ряд | {{Орден Ленина}} | {{Орден Октябрьской Революции}} | {{Орден Красного Знамени}} }}"
},
"автограф": {
"aliases": [
"Автограф"
],
"label": "автограф",
"type": "wiki-file-name",
"description": "отсканированная подпись персоны (P109)"
},
"ширина автографа": {
"aliases": [
"Ширина автографа"
],
"label": "ширина автографа",
"type": "number"
},
"сайт": {
"aliases": [
"Сайт"
],
"label": "сайт",
"type": "url",
"description": "официальный сайт (P856)",
"example": "example.com"
},
"викисклад": {
"aliases": [
"Викисклад"
],
"label": "викисклад",
"description": "название категории на Викискладе (P373)",
"deprecated": true,
"type": "line"
},
"учёное звание": {
"aliases": [
"Учёное звание"
],
"label": "учёное звание",
"type": "string",
"description": "учёное звание",
"example": "{{Учёное звание||0}}",
"autovalue": "{{Учёное звание||}}"
}
},
"description": "Шаблон-карточка для статей о политиках.",
"paramOrder": [
"имя",
"оригинал имени",
"изображение",
"ширина",
"описание изображения",
"имя при рождении",
"псевдонимы",
"дата рождения",
"место рождения",
"дата смерти",
"место смерти",
"гражданство",
"род деятельности",
"образование",
"учёная степень",
"учёное звание",
"вероисповедание",
"партия",
"основные идеи",
"отец",
"мать",
"супруг",
"супруга",
"дети",
"награды",
"автограф",
"ширина автографа",
"сайт",
"викисклад",
"nocat",
"from"
],
"format": "block"
}
</templatedata>
<includeonly>
[[Категория:Шаблоны-карточки:Личности]]
[[Категория:Шаблоны-карточки:Политика]]
</includeonly>
20627691b0800f1de81471e82cb15ed1027bfbd3
Шаблон:Карточка/изображение
10
213
475
474
2024-08-16T05:22:07Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{#if:{{{1|}}}|
{{#switch:{{{1|}}}
|-=-
|none=
|нет=
|{{#switch:{{str left|{{{1|}}}|1}}
|[|<|{|={{{1|}}}
|[[Файл:{{{1|}}}|{{#if:{{{size|{{{2|}}}}}}|{{#ifeq:{{str rightc|{{{size|{{{2|}}}}}}|2}}|px|{{{size|{{{2|}}}}}}|{{#ifeq:{{str rightc|{{{size|{{{2|}}}}}}|3}}|пкс|{{{size|{{{2|}}}}}}|{{{size|{{{2|}}}}}}px}}}}|274x400px}}{{#if:{{{caption|}}}|{{!}}{{{caption|}}}}}|frameless{{#if:{{{border|}}}|{{!}}border}}{{#if:{{{alt|}}}|{{!}}alt={{{alt|}}}}}]]
}}{{#if:{{{caption|}}}
|<span class="media-caption" style="display:block;">{{{caption|}}}</span>
}}
}}
}}</includeonly><!--
-->{{#if: {{{2|}}} | [[Категория:Википедия:Страницы с использованием устаревшего формата параметра Карточка/изображение]] }}<!--
-->{{#ifeq: {{str find|{{{size|{{{2|}}}}}}|pxpx}} | -1 || [[Категория:Википедия:Изображение с pxpx в размере]] }}<noinclude>{{doc}}</noinclude>
c54dd8fbf131f3bc584add9cd834eea7b4f45e43
Шаблон:Str find
10
214
477
476
2024-08-16T05:22:14Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{ {{{|safesubst:}}}#invoke:String|str_find|source={{{1|}}}|{{{2|}}}}}<noinclude>
{{doc}}
<!-- Add categories and interwikis to the /doc subpage, not here! -->
</noinclude>
18d1469d30d27a82ee15fd2fb1ca12a34b5f5e87
Шаблон:Навигационная таблица
10
215
479
478
2024-08-16T05:22:16Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{#invoke:Navbox|navbox}}</includeonly>{{#ifeq: {{NAMESPACE}} | Шаблон
| {{#switch: {{{1|{{{border|}}}}}}
| child | subgroup | none =
| {{#ifeq: {{{имя|{{{name|}}}}}} | {{PAGENAME}}
|
| {{#if:{{yesno|{{{tracking|}}}|no=1|yes=|blank=}}
|
| {{#if: {{{имя|{{{name|}}}}}}
| {{#ifeq:{{ROOTPAGENAME}}|Работа недели||{{no-doc|[[Категория:Навигационные шаблоны, у которых нужно проверить параметр Имя]]}}}}
| [[Категория:Навигационные шаблоны, у которых предположительно недостаёт параметра Имя]]
}}
}}
}}
}}
}}<noinclude>
{{doc}}
</noinclude>
b1c7f6e61d3b9cdd1daaf4d95e30e299a1d9eb5c
Шаблон:Tp
10
216
481
480
2024-08-16T05:22:19Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
#перенаправление [[Шаблон:Tlp]]
d882ad71d959bf88034ac86b892a2686c44e6a87
Шаблон:Tlp
10
217
483
482
2024-08-16T05:22:20Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{{{{|safesubst:}}}#invoke: Template call code | withParams | _link = 1 }}<noinclude>{{doc}}</noinclude>
36c309cb28ccf0901f4fff46cbd35cdabcf00661
Шаблон:Para
10
218
485
484
2024-08-16T05:22:22Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<code style="white-space:nowrap;">|{{#if:{{{1|}}}|<span style="color:#767600;">{{{1}}}</span> = {{{2|}}}|<span style="color:#767600;">{{{2|}}}</span>}}</code><noinclude>
{{doc}}
</noinclude>
2fd0e9f403fb5a42e97b773185e89bc43323bb37
Шаблон:Tnav
10
219
487
486
2024-08-16T05:22:24Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{t|{{{1|}}}|nav|comment={{{comment|}}}}}<noinclude>
{{doc-inline}}
Это — обёртка для шаблона {{t|tl}}, предназначенная для использования в блоках навигации. Она передаёт в него флаг <code>nav</code> и комментарий в параметре {{para|comment}}.
{{шаблоны для документирования}}
{{doc-end}}
[[Категория:Шаблоны:Ссылки на шаблоны]]
[[Категория:Шаблоны:Для навигационных шаблонов]]
</noinclude>
583d607aa213790ae32dda4018a413255493e42b
Шаблон:High-use
10
220
489
488
2024-08-16T05:22:25Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<noinclude>{{к удалению|2024-04-08}}
</noinclude><noinclude>{{к объединению|2020-11-10|Шаблон:СИШ}}</noinclude>{{ombox
| type = style
| image = [[File:OOjs UI icon alert-yellow.svg|40px|alt=|link=]]
| text =
Этот {{#switch: {{NAMESPACE}} | Модуль = модуль | #default = шаблон }} используется на многих страницах, поэтому изменения в нём будут заметны многим. Пожалуйста, протестируйте любые изменения в песочнице или на вашей личной подстранице. Рассмотрите возможность обсуждения изменений на [[{{#switch: {{SUBPAGENAME}}
| doc | sandbox = {{TALKSPACE}}:{{BASEPAGENAME}}
| #default = {{TALKPAGENAME}}
}}|странице обсуждения]] или [[ВП:Форум|форуме]] перед их внесением.<br>[https://templatecount.toolforge.org/index.php?lang=ru&name={{PAGENAMEE}}&namespace={{NAMESPACENUMBER}} Узнать число включений].
}}<includeonly>{{no-doc|nocat={{{nocat|}}}| [[Категория:Шаблоны:Критические]] }}</includeonly><noinclude>{{doc}}</noinclude>
ded73fd2acfa6bc0f9f309d7d66181c33a520198
Шаблон:Подстраницы шаблона Карточка
10
221
491
490
2024-08-16T05:22:26Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{Навигационная таблица
|имя = Подстраницы шаблона Карточка
|state = {{{state|}}}
|класс_списков = hlist hlist-items-nowrap
|заголовок = Подстраницы шаблона {{tnav|Карточка}}
|tracking = <includeonly>no</includeonly>
|группа1 = {{!}}вверху=
|список1 =
* {{tnav|карточка/название}} (заголовок без уточнения)
* {{tnav|карточка/имя}} (заголовок в обратном порядке и без уточнения)
|группа2 = {{!}}вверху2=
|список2 =
* {{tnav|карточка/оригинал названия}} (свойство [[d:P:P1705|P1705]])
* {{tnav|карточка/оригинал названия произведения}} (свойство [[d:P:P1476|P1476]])
* {{tnav|карточка/официальное название}} (свойство [[d:P:P1448|P1448]])
* {{tnav|карточка/оригинал имени}} (свойство [[d:P:P1559|P1559]])
|группа3 = Разное
|список3 =
* {{tnav|карточка/изображение}}
* {{tnav|карточка/Изображение рядом}}
* {{tnav|карточка/флаг и герб}} (свойства [[d:p:P41|P41]] и [[d:p:P94|P94]])
* {{tnav|карточка/медали}} (свойство [[d:p:P166|P166]])
* {{tnav|карточка/хронология}} (свойства [[d:p:P155|P155]] и [[d:p:P156|P156]])
* {{tnav|карточка/период}} (свойства [[d:p:P580|P580]] и [[d:p:P582|P582]])
* {{tnav|карточка/коды в каталогах}} (свойство [[d:p:P528|P528]])
* {{tnav|карточка/блок}}
* {{tnav|карточка/блок с маркерами}}
|группа4 = {{!}}внизу=
|список4 =
* {{tnav|карточка/Викиданные}}
* {{tnav|карточка/Викисклад}} (свойство [[d:P:P373|P373]])
* {{tnav|карточка/Викитека}}
* {{tnav|карточка/Викиучебник}}
* {{tnav|карточка/Викицитатник}}
|класс_внизу = hlist
|внизу =
; См. также
: [[Википедия:Шаблоны-карточки]]
: [[:Категория:Шаблоны:Для шаблонов-карточек]]
}}<noinclude>
[[Категория:Навигационные шаблоны:Для шаблонов]]
</noinclude>
f7c3cb19df3f1a23fdde48e58f259bb1f952d0ed
Шаблон:Карточка/изображение/doc
10
222
493
492
2024-08-16T05:22:26Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{docpage}}
{{high-use}}
Используется в [[Википедия:Шаблоны-карточки|шаблонах-карточках]] для вывода полей изображений, которые не нужно привязывать к Викиданным (в противном случае используется <code>{{tp|wikidata|P18|caption=<nowiki>{{{описание изображения|}}}</nowiki>|size=<nowiki>{{{ширина|}}}</nowiki>}}</code>).
== Заполнение в статьях ==
Для изображений в формате «'''<nowiki>[[Файл:<Имя>|…]]</nowiki>'''» (и вообще для любого параметра, начинающегося с «'''['''», «'''{'''» или «'''<'''») текст вставится без изменения:
<nowiki>{{{изображение|}}}</nowiki>
Если же просто указано название изображения, то оно оформится так:
<nowiki>[[Файл:{{{изображение|}}}|274x400px]]</nowiki>
== Использование шаблона ==
Вставляется в шаблон {{t|карточка}} — либо в поле {{para|изображение}}, либо в поле {{para|текстN}} (в таком случае может понадобиться сбросить паддинги: {{para|стиль_текстаN|padding:0;}}).
Формат применения:
<nowiki>| изображение = {{Карточка/изображение|{{{изображение|}}}|size={{{ширина|}}}|caption={{{описание изображения|}}}}}</nowiki>
== TemplateData ==
<templatedata>
{
"description": "Этот шаблон используется для вставки параметра изображения.",
"params": {
"1": {
"label": "1",
"description": "Изображение в любом виде, если '''none''' или '''нет''', то игнорируется.",
"type": "string",
"required": false
},
"caption": {
"label": "caption",
"description": "Подпись под изображением.",
"type": "string",
"required": false
},
"size": {
"aliases": [
"2"
],
"label": "size",
"description": "Его размер, можно с '''px''' или без, по-умолчанию — '''274x400px'''.",
"type": "string"
}
},
"paramOrder": [
"1",
"size",
"caption"
]
}
</templatedata>
== См. также ==
* [[Шаблон:Карточка/изображение/тесты]] (для проверки изменений)
* {{tl|URL}}
{{Подстраницы шаблона Карточка}}
<includeonly>
[[Категория:Шаблоны:Подстраницы шаблона Карточка|изображение]]
</includeonly>
1a53aa3106ad42492ac93048c8554950e40a1bf8
Шаблон:Fmbox
10
223
495
494
2024-08-16T05:24:30Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{#invoke:Message box|fmbox}}<noinclude>
{{documentation}}
<!-- Add categories and interwikis to the /doc subpage, not here! -->
</noinclude>
dfb511d767bd2208627c0874ccf91faf6b8551cc
Шаблон:Параметры шаблона
10
224
497
496
2024-08-16T05:24:33Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<span title="Смотреть с помощью инструмента Templatetiger">[//dimastbkbot.toolforge.org/template_params/?template={{urlencode:{{{1|{{PAGENAME}}}}}}}&lang=ruwiki использование шаблона]</span><!-- • <span title="Смотреть с помощью инструмента Templatetiger">[//tools.wmflabs.org/templatetiger/template-parameter.php?template={{urlencode:{{{1|{{PAGENAME}}}}}}}&lang=ruwiki параметры]--> <small>[[Шаблон:Параметры шаблона|[?]]]</small><!--</span>--><noinclude>{{doc}}</noinclude>
dcd4178efbe8f098263608dce37fd93b55b863c4
Модуль:Message box/fmbox.css
828
225
499
498
2024-08-16T05:24:34Z
DuOfOrl
5
1 версия импортирована
sanitized-css
text/css
/* Скопировано из [[:en:Module:Message box/fmbox.css]] с изменениями */
.fmbox {
clear: both;
margin: 0.2em 0;
width: 100%;
border: 1px solid var(--border-color-base, #a2a9b1);
background-color: var(--background-color-neutral-subtle, #f8f9fa); /* Default "system" gray */
box-sizing: border-box;
}
.fmbox-warning {
border: 1px solid #bb7070; /* Dark pink */
background-color: #ffdbdb; /* Pink */
}
.fmbox-editnotice {
background-color: transparent;
}
.fmbox .mbox-text {
border: none;
/* @noflip */
padding: 0.25em 0.9em;
width: 100%;
}
.fmbox .mbox-image {
border: none;
/* @noflip */
padding: 2px 0 2px 0.9em;
text-align: center;
}
.fmbox .mbox-imageright {
border: none;
/* @noflip */
padding: 2px 0.9em 2px 0;
text-align: center;
}
.fmbox .mbox-invalid-type {
text-align: center;
}
/* Хак, TODO: посмотреть, как оно на самом деле работает */
.fmbox .mbox-textsmall-div {
font-size: 90%;
}
/* [[Категория:Модули:Подстраницы CSS]] */
313e9f5515a4f12a2a44d6c8d57f74cbda4bb464
Шаблон:Государство
10
122
500
287
2024-08-16T05:28:56Z
DuOfOrl
5
wikitext
text/x-wiki
{{Карточка
|имя = Государство
|автозаголовки = да
|from = {{{from|}}}
|вверху0 = {{#switch: {{{Статус|}}}
| виртуальное = [[Виртуальное государство]]
| особый = {{#if: {{{Спорный статус|}}} | {{{Особый спорный статус|}}} }}
| Непризнанное
| непризнанное = {{#if: {{{Спорный статус|}}} | [[Непризнанные и частично признанные государства|Непризнанное государство]] }}
| Частично признанное
| частично признанное = {{#if: {{{Спорный статус|}}} | [[Непризнанные и частично признанные государства|Частично признанное государство]] }}
}}
|вверху = {{карточка/название|{{{Русское название|}}}|from={{{from|}}}}}
|вверху2 = {{{Оригинальное название|}}}
|изображение = {{Карточка/флаг и герб
| флаг = {{{Флаг|}}}
| флаг ширина = {{{Размер флага|}}}{{{размер флага|}}}
| флаг подпись = [[{{#if: {{{Ссылка на флаг|}}} | {{{Ссылка на флаг}}} | Флаг {{{Родительный падеж}}} }}|Флаг]]
| герб = {{{Герб|}}}
| герб ширина = {{{Размер герба|}}}{{{размер герба|}}}
| герб подпись = {{#if: {{{Отображаемая подпись герба|}}} | {{{Отображаемая подпись герба}}} | {{#if: {{{Вместо герба|}}} | [[{{{Вместо герба}}} {{{Родительный падеж}}}|{{{Вместо герба}}}]] | [[Герб {{{Родительный падеж}}}|Герб]] }} }}
|from={{{from|}}}}}
|текст1 = {{br separated entries
| {{#if: {{{Девиз|}}} | [[Девиз]]: ''«{{{Девиз}}}»'' }}
| {{#if: {{{Перевод девиза|}}} | ''«{{{Перевод девиза}}}»'' }}
}}
|текст2 = {{#if: {{{Без гимна|}}} || {{#if: {{{Название гимна|}}} | [[Государственный гимн|Гимн]]: [[Гимн {{{Родительный падеж}}}|''«{{{Название гимна}}}»'']] | [[Гимн {{{Родительный падеж<noinclude>|</noinclude>}}}|Государственный гимн {{{Родительный падеж<noinclude>|</noinclude>}}}]] }}{{#if: {{{Аудио|}}} | {{#if: {{{Аудио|}}} | <sup>[[Файл:Loudspeaker.svg|11px|link=Файл:{{{1}}}|Информация о файле]] [[:Media:{{{Аудио|}}}|слушать]]</sup> }} }} }}
|текст3 = {{#if: {{{На карте|}}} | {{Карточка/изображение|{{{На карте|}}}|size={{#if: {{{Размер карты|}}}{{{размер карты|}}} | {{{Размер карты|}}}{{{размер карты|}}} | 300x300px }}|caption={{{Подпись к карте|}}}{{{подпись к карте|}}}}}<!--
-->{{#if: {{{На карте2|}}} | <br>[[Файл:{{{На карте2}}}|{{{Размер карты2|{{{размер карты2|300x300px}}}}}}]]{{#if:{{{Подпись к карте 2|}}}{{{подпись к карте 2|}}}|<br>{{{Подпись к карте 2|{{{подпись к карте 2|}}}}}} }} }} }}
|заголовок4 = {{#if: {{{sovereignty_type|}}} | {{{sovereignty_type}}} | [[История {{{Родительный падеж}}}|История]] }}
|стиль_заголовка4 = padding-bottom:0; border-bottom:0; text-align:left;
|блок5 =
{{Карточка/блок с маркерами
|метка1 = {{nobr|{{{Дата1}}}}}
|текст1 = {{{Этап1|}}}
|метка2 = {{nobr|{{{Дата2}}}}}
|текст2 = {{{Этап2|}}}
|метка3 = {{nobr|{{{Дата3}}}}}
|текст3 = {{{Этап3|}}}
|метка4 = {{nobr|{{{Дата4}}}}}
|текст4 = {{{Этап4|}}}
|метка5 = {{nobr|{{{Дата5}}}}}
|текст5 = {{{Этап5|}}}
|метка6 = {{nobr|{{{Дата6}}}}}
|текст6 = {{{Этап6|}}}
|метка7 = {{nobr|{{{Дата7}}}}}
|текст7 = {{{Этап7|}}}
|метка8 = {{nobr|{{{Дата8}}}}}
|текст8 = {{{Этап8|}}}
|метка9 = {{nobr|{{{Дата9}}}}}
|текст9 = {{{Этап9|}}}
|метка10 = {{nobr|{{{Дата10}}}}}
|текст10 = {{{Этап10|}}}
|метка11 = {{nobr|{{{Дата11}}}}}
|текст11 = {{{Этап11|}}}
|метка12 = {{nobr|{{{Дата12}}}}}
|текст12 = {{{Этап12|}}}
|from={{{from|}}}}}
|заголовок6 = -
|метка7 = [[Основание государства|{{#if: {{{Основана|}}} | Основана | Основано }}]]
|текст7 = {{{Основана|}}}{{{Основано|}}}
<!-- СПОРНЫЙ СТАТУС -->
<!-- Спорный статус заполнен -->
|метка8 = [[Основание государства|Дата образования]]
|текст8 = {{#if: {{{Спорный статус|}}} | {{{Дата образования|}}} }}
|метка9 = Провозглашение независимости
|текст9 = {{#if: {{{Спорный статус|}}} | {{#if: {{{Провозглашение независимости|}}} | {{{Провозглашение независимости}}} {{#if: {{{Независимость от|}}} | (от {{{Независимость от}}}) }} }} }}
|метка10 = [[Международно-правовое признание|Дипломатическое признание]]
|текст10 = {{#if: {{{Спорный статус|}}} | {{{Дипломатическое признание|}}} }}
<!-- Спорный статус не заполнен -->
|метка11 = {{#if: {{{Отображаемый тип независимости|}}} | {{{Отображаемый тип независимости}}} | [[Суверенитет|{{#if: {{{Даты независимости|}}} | Даты | Дата }} независимости]] }}
|текст11 = {{#if: {{{Спорный статус|}}} || {{#if: {{{Дата независимости|}}}{{{Даты независимости|}}} | {{{Дата независимости|{{{Даты независимости|}}}}}} {{#if: {{{Независимость от|}}} | (от {{{Независимость от}}}) }} }} }}
<!-- / СПОРНЫЙ СТАТУС -->
|метка12 = [[Официальный язык|{{#if: {{{Язык|}}} | Официальный язык | Официальные языки }}]]
|текст12 = {{{Язык|{{{Языки|}}}}}}
|метка13 = [[Столица]]
|текст13 = {{{Столица|}}}
|метка14 = {{#if: {{{Крупнейший город|}}} | Крупнейший город | Крупнейшие города }}
|текст14 = {{{Крупнейший город|}}}{{{Крупнейшие города|}}}
|метка15 = [[Форма государственного правления|Форма правления]]
|текст15 = {{{Форма правления|}}}
|метка16 = [[Форма государственного устройства|Государственный строй]]
|текст16 = {{{Государственный строй|}}}
|метка17 = {{{Должность руководителя 1|{{{Должности руководителей}}}}}}
|текст17 = {{{Руководитель 1|{{{Руководители|}}}}}}
|метка18 = {{{Должность руководителя 2}}}
|текст18 = {{{Руководитель 2|}}}
|метка19 = {{{Должность руководителя 3}}}
|текст19 = {{{Руководитель 3|}}}
|метка20 = {{{Должность руководителя 4}}}
|текст20 = {{{Руководитель 4|}}}
|метка21 = {{{Должность руководителя 5}}}
|текст21 = {{{Руководитель 5|}}}
|метка22 = {{{Должность руководителя 6}}}
|текст22 = {{{Руководитель 6|}}}
|метка23 = [[Государственная религия|Гос. религия]]
|текст23 = {{{Государственная религия|}}}
|блок24 =
{{Карточка/блок с маркерами
|подзаголовок = [[Территория государства|Территория]]
|метка1 = Всего
|текст1 = {{br separated entries
| {{число|{{{Территория|}}}|км²}}{{#if: {{{Место по территории|}}} | ([[Список государств и зависимых территорий по площади|{{{Место по территории}}}-я в мире]]) }}
| {{число|{{{Территория2|}}}|км²}}
}}
|метка2 = % водной поверхности
|текст2 = {{#ifeq: {{{Процент воды|}}} | - || {{{Процент воды|}}} }}
|from={{{from|}}}}}
|блок25 =
{{Карточка/блок с маркерами
|подзаголовок = [[{{Население государства|{{PAGENAME}}}}]]
|метка1 = Оценка {{#if: {{{Год оценки|}}} | ({{{Год оценки}}}) }}
|текст1 = {{br separated entries
| {{число|{{{Население|}}}|чел.}}{{#if: {{{Место по населению|}}} | ([[Список стран по населению|{{{Место по населению}}}-е]]) }}
| {{число|{{{Население2|}}}|чел.}}
}}
|метка2 = Перепись {{#if: {{{Год переписи|}}} | ({{{Год переписи}}}) }}
|текст2 = {{число|{{{Население по переписи|}}}|чел.}}
|метка3 = [[Плотность населения|Плотность]]
|текст3 = {{число|{{{Плотность населения|}}}|чел./км²}}{{#if: {{{Место по плотности|}}} | ([[Список стран по плотности населения|{{{Место по плотности}}}-я]]) }}
|from={{{from|}}}}}
|блок26 =
{{Карточка/блок с маркерами
|подзаголовок = [[Валовой внутренний продукт|ВВП]]
|метка1 = Итого {{#if: {{{Год расчёта ВВП|}}} | ({{{Год расчёта ВВП}}}) }}
|текст1 = {{число|{{{ВВП|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП|}}} | ([[Список стран по ВВП (ППС)|{{{Место по ВВП}}}-й]]) }}
|метка2 = На душу населения
|текст2 = {{число|{{{ВВП на душу населения|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП на душу населения|}}} | ([[Список стран по ВВП (ППС) на душу населения|{{{Место по ВВП на душу населения}}}-й]]) }}
|from={{{from|}}}}}
|блок27 =
{{Карточка/блок с маркерами
|подзаголовок = [[Валовой внутренний продукт|ВВП]] <span style="font-weight:normal;">([[Паритет покупательной способности|ППС]])</span>
|метка1 = Итого {{#if: {{{Год расчёта ВВП (ППС)|}}} | ({{{Год расчёта ВВП (ППС)}}}) }}
|текст1 = {{число|{{{ВВП (ППС)|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (ППС)|}}} | ([[Список стран по ВВП (ППС)|{{{Место по ВВП (ППС)}}}-й]]) }}
|метка2 = На душу населения
|текст2 = {{число|{{{ВВП (ППС) на душу населения|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (ППС) на душу населения|}}} | ([[Список стран по ВВП (ППС) на душу населения|{{{Место по ВВП (ППС) на душу населения}}}-й]]) }}
|from={{{from|}}}}}
|блок28 =
{{Карточка/блок с маркерами
|подзаголовок = [[Валовой внутренний продукт|ВВП]] <span style="font-weight:normal;">(номинал)</span>
|метка1 = Итого {{#if: {{{Год расчёта ВВП (номинал)|}}} | ({{{Год расчёта ВВП (номинал)}}}) }}
|текст1 = {{число|{{{ВВП (номинал)|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (номинал)|}}} | ([[Список стран по ВВП (номинал)|{{{Место по ВВП (номинал)}}}-й]]) }}
|метка2 = На душу населения
|текст2 = {{число|{{{ВВП (номинал) на душу населения|}}}|[[Доллар США|долл.]]}}{{#if: {{{Место по ВВП (номинал) на душу населения|}}} | ([[Список стран по ВВП (номинал) на душу населения|{{{Место по ВВП (номинал) на душу населения}}}-й]]) }}
|from={{{from|}}}}}
|метка29 = [[Индекс человеческого развития|ИЧР]] {{#if: {{{Год расчёта ИРЧП|}}} | <span style="font-weight:normal;">({{{Год расчёта ИРЧП}}})</span> }}
|текст29 = {{{ИРЧП|}}}{{#if: {{{Уровень ИРЧП|}}} | ({{{Уровень ИРЧП}}}{{#if: {{{Место по ИРЧП|}}} | ; [[Список стран по индексу человеческого развития|{{{Место по ИРЧП}}}-е место]] }}) }}
|метка30 = [[Названия жителей]]
|текст30 = {{{Этнохороним|}}}
|метка31 = [[Валюта]]
|текст31 = {{{Валюта|}}}
|метка32 = [[Домен верхнего уровня|Интернет-домен]]
|текст32 = {{{Домен|}}}{{{Домены|}}}
|метка33 = [[ISO 3166-1|Код ISO]]
|текст33 = [https://www.iso.org/obp/ui/#iso:code:3166:{{{ISO|{{{Код ISO|}}}}}} {{{ISO|{{{Код ISO|}}}}}}]
|метка34 = [[Список кодов МОК|Код МОК]]
|текст34 =
|метка35 = [[Список телефонных кодов стран|Телефонный код]]
|текст35 = {{#if: {{{Телефонный код|}}} | {{#ifeq: {{{Телефонный код|}}} | - | - | +{{{Телефонный код}}} }} }}
|метка36 = Часовой пояс
|текст36 = {{{Часовой пояс|}}}{{{Часовые пояса|}}}
|метка37 = Автомобильное движение
|текст37 = {{{Автомобильное движение|}}}
|текст38 = {{{Примечания|}}}
|стиль_текста38 = border-top:1px solid #a2a9b1; color:#54595d; padding-top:0.5em; text-align:left;
|внизу = {{#if: {{{lat_deg|}}}
| {{coord
|1 = {{{lat_deg|}}}
|2 = {{{lat_min|0}}}
|3 = {{{lat_sec|0}}}
|4 = {{#if: {{{lat_dir|}}} | {{{lat_dir}}} | N }}
|5 = {{{lon_deg|}}}
|6 = {{{lon_min|0}}}
|7 = {{{lon_sec|0}}}
|8 = {{#if: {{{lon_dir|}}} | {{{lon_dir}}} | E }}
|9 = type:{{#if: {{{region|}}} | landmark_region:{{{region}}} | landmark }}
|scale = {{#if: {{{CoordScale|}}} | {{{CoordScale}}} | 100000 }}
|format = dms
|display = inline
|yandex = 1
}}
}}
}}{{#if: {{{nocat|}}}{{NAMESPACE}} || <!--
-->{{#switch: {{{Статус|}}}
| Виртуальное
| виртуальное = [[Категория:Виртуальные государства]]
| Непризнанное
| непризнанное = [[Категория:Непризнанные государства]]
| Частично признанное
| частично признанное = [[Категория:Частично признанные государства]]
| особый = {{#if: {{{Спорный статус|}}} | {{#if: {{{Особая категория|}}}|[[Категория:{{{Особая категория|}}}]]|[[Категория:Государства по алфавиту]]}} }}
| [[Категория:Государства по алфавиту]]
}}
}}<noinclude>{{doc}}</noinclude>
12e434cc4652968106aad81f2df304b4ae90d1eb
Шаблон:Карточка/флаг и герб
10
170
501
383
2024-08-16T05:43:45Z
DuOfOrl
5
wikitext
text/x-wiki
{{#if: {{{флаг|}}}{{{герб|}}}|<table role="presentation" style="background:inherit; border-collapse:collapse; width:100%; display:table; text-align:center;">
<tr>
{{#if: {{{флаг|}}}|<td style<nowiki>=</nowiki>"vertical-align: middle">{{Карточка/изображение|{{{флаг|}}}|border=true|size={{#if:{{{флаг ширина|}}}|{{{флаг ширина|}}}|160x160px}}|alt={{#if:{{{флаг подпись|}}} | {{{флаг подпись}}} | Флаг }} }}</td>}}
{{#if: {{{герб|}}}|<td style<nowiki>=</nowiki>"vertical-align: middle">{{Карточка/изображение|{{{герб|}}}|size={{#if:{{{герб ширина|}}}|{{{герб ширина|}}}|90x160px}}|alt={{#if:{{{герб подпись|}}} | {{{герб подпись}}} | Герб }} }}</td>}}
</tr>
{{#if:{{{флаг|}}}{{{герб|}}}|<tr>
{{#if:{{{флаг|}}}|<td>{{#if:{{{флаг подпись|}}} | {{{флаг подпись}}} | Флаг }}</td>}}
{{#if:{{{герб|}}}|<td>{{#if:{{{герб подпись|}}} | {{{герб подпись}}} | Герб }}</td>}}
</tr>}}
</table>}}
<noinclude>{{doc}}</noinclude>
4070282b253031db82c261d97dc40100ca06e6ec
Шаблон:Карточка
10
129
502
301
2024-08-16T06:04:54Z
DuOfOrl
5
wikitext
text/x-wiki
{{#if:{{{имя|}}}|{{#ifeq:{{{имя|}}}|-||{{#if:{{{цвет|}}}|{{#tag:templatestyles|
|wrapper=.infobox-{{#invoke:Hash|main|{{{имя}}} {{{вверху0|}}} {{{вверху|}}} {{{вверху2|}}}}}
|src=Шаблон:Цвет/{{{цвет|}}}.css
}}}}}}}}<table class="infobox infobox-{{#invoke:Hash|main|{{{имя}}} {{{вверху0|}}} {{{вверху|}}} {{{вверху2|}}}}} {{{класс_тела|}}}" style="{{{стиль_тела|}}}" {{#if:{{{имя|}}}|{{#ifeq:{{{имя|}}}|-||data-name="{{{имя}}}"}}}} {{#if:{{{from|}}}|{{#ifeq:{{{from|}}}|-||data-from="{{{from}}}"}}}}><!--
Вверху0
-->{{#if:{{{вверху0|}}}|<tr><td colspan="2" class="{{{класс_вверху0|}}}" style="text-align:center; {{{стиль_вверху0|}}}">{{{вверху0}}}</td></tr>}}<!--
Вверху
-->{{#if:{{{вверху|}}}|<tr><th colspan="2" scope="colgroup" class="infobox-above {{{класс_вверху|}}}" style="{{{стиль_вверху|}}}">{{{вверху}}}</th></tr>}}<!--
Вверху2
-->{{#if:{{{вверху2|}}}|<tr><td colspan="2" class="{{{класс_вверху2|}}}" style="text-align:center; {{{стиль_вверху2|}}}">{{{вверху2}}}</td></tr>}}<!--
Вверху3
-->{{#if:{{{вверху3|}}}|<tr><td colspan="2" class="{{{класс_вверху3|}}}" style="text-align:center; {{{стиль_вверху3|}}}">{{{вверху3}}}</td></tr>}}<!--
Изображение
-->{{#if:{{{изображение|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения|}}}" style="{{{стиль_изображения|}}}"> {{{изображение}}} {{#if:{{{подпись|}}}|
<div class="media-caption" style="{{{стиль_подписи|}}}">{{{подпись}}}</div>}}</td></tr>}}<!--
Изображение2
-->{{#if:{{{изображение2|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения2|}}}" style="{{{стиль_изображения2|}}}"> {{{изображение2}}} {{#if:{{{подпись2|}}}|
<div class="media-caption" style="{{{стиль_подписи2|}}}">{{{подпись2}}}</div>}}</td></tr>}}<!--
Изображение3
-->{{#if:{{{изображение3|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения3|}}}" style="{{{стиль_изображения3|}}}"> {{{изображение3}}} {{#if:{{{подпись3|}}}|
<div class="media-caption" style="{{{стиль_подписи3|}}}">{{{подпись3}}}</div>}}</td></tr>}}<!--
Строки
-->{{#invoke:Infobox|renderLines}}<!--
Внизу
-->{{Карточка/внизу|
стиль_внизу_общий={{{стиль_внизу|}}}|
класс_внизу={{{класс_внизу|}}}|
внизу={{{внизу|}}}}}<!--
Внизу N
-->{{#invoke:Transclude|npc|Карточка/внизу|
стиль_внизу_общий={{{стиль_внизу|}}}|
стиль_внизу=|
класс_внизу=|
внизу=}}
</table><includeonly><!--
статьи
-->{{#if:{{NAMESPACE}}||<!--
-->{{#if:{{{имя|}}}||[[Категория:Статьи с шаблонами-карточками без имени]]}}<!--
-->{{#ifeq:{{{имя|}}}|{{subst:PAGENAME}}|[[Категория:Статьи с шаблонами-карточками без имени]]}}<!--
-->}}<!--
шаблоны
-->{{#ifeq:{{NAMESPACENUMBER}}|10|<!--
-->{{#if:{{{имя|}}}||[[Категория:Шаблоны-карточки без имени]]}}<!--
-->{{#ifeq:{{{имя|}}}|{{subst:PAGENAME}}|[[Категория:Шаблоны-карточки без имени]]}}<!--
-->{{#if:{{{название|}}}{{{стиль_названия|}}}|[[Категория:Шаблоны с использованием параметра «название» в шаблоне «Карточка»]]}}<!--
-->{{#if:{{{подпись|}}}{{{стиль_подписи|}}}{{{подпись2|}}}{{{стиль_подписи2|}}}{{{подпись3|}}}{{{стиль_подписи3|}}}|[[Категория:Шаблоны с использованием параметра «подпись» в шаблоне «Карточка»]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_тела|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_названия|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху2|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху3|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи2|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи3|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_заголовков|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_меток|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_текста|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_внизу|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifeq:{{{имя|}}}|{{PAGENAME}}|<!--
-->[[Категория:Шаблоны-карточки по алфавиту|{{ucfirst:{{без начала|{{PAGENAME}}|Карточка }}}}]]<!--
-->{{#if:{{{стиль_тела|}}}{{{стиль_вверху|}}}{{{стиль_заголовков|}}}{{{стиль_внизу|}}}|[[Категория:Руниверсалис:Шаблоны-карточки с явным указанием стилей]]}}<!--
-->}}<!--
-->}}<!--
любое пространство имён
-->{{#if:{{{название|}}}{{{стиль_названия|}}}|[[Категория:Мемнотация:Страницы с использованием параметра «название» в шаблоне «Карточка»]]}}<!--
-->{{#if:{{{подпись|}}}{{{стиль_подписи|}}}{{{подпись2|}}}{{{стиль_подписи2|}}}{{{подпись3|}}}{{{стиль_подписи3|}}}|[[Категория:Мемнотация:Страницы с использованием параметра «подпись» в шаблоне «Карточка»]]}}</includeonly><noinclude>{{Карточка/doc}}</noinclude>
b984bb747e87f65667710f8762f83fb38e872ef5
Шаблон:Карточка/doc
10
226
504
503
2024-08-16T06:07:43Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{docpage}}
{{OnLua|Infobox|renderLines|module2=Transclude|function2=npc}}
{{СИШ}}
Это меташаблон для создания [[Википедия:Шаблоны-карточки|шаблонов-карточек]].
== Параметры ==
=== Служебные ===
; имя: Имя шаблона, необходимое для корректной работы служебных инструментов на всех страницах, где используется шаблон. Для простоты можно использовать <code><nowiki>{{subst:PAGENAME}}</nowiki></code>.
; автозаголовки: Указание «да» приводит к автоматическому скрытию заголовков, после которых, вплоть до следующего заголовка, все поля пусты. Возможно использовать фиктивные заголовки «-» для прерывания области скрытия. Будет работать некорректно, если требуется указать два заголовка подряд — например, при использовании многоуровневых заголовков. В этом случае рекомендуется явно указать «нет» на случай смены значения по умолчанию с «нет» на «да».
; from: Указывается элемент Викиданных, из которого берётся информация.
=== Основные ===
; вверху: Текст, отображаемый вверху таблицы. Обычно это название предмета статьи.
; вверху2: Дополнительный текст, отображаемый вверху таблицы. Обычно используется для оригинального названия.
; вверху3: Дополнительный текст, отображаемый вверху таблицы.
; изображение: Изображение, которое будет отображено под основным заголовком в правой части таблицы (правее заголовков/списков). Параметр ''изображение'' допускает стандартный викикод для отображения. Для разных типов параметра можно использовать {{tl|Форматирование изображения}}. Обычно предпочтительнее использовать код <code><nowiki>{{wikidata|P18|{{{изображение|}}}|caption={{{описание изображения|}}}}}</nowiki></code>.
; подпись: Подпись под изображением. Отображается только в том случае, если задано изображение. При использовании {{tlp|wikidata|P18}} не заполняется.
; изображение2: Дополнительное изображение.
; изображение3: Дополнительное изображение.
; заголовок<sub>n</sub>: Используется для создания заголовков в ряду. Этот и следующие 2 параметра работают при n≥1.
; метка<sub>n</sub>: Используется для подписи текста
; текст<sub>n</sub>: Используется для принятия параметров в специализированных шаблонах-карточках.
; блок<sub>n</sub>: Технический параметр, используется для вставки блоков, заключённых в <tr>, таких как {{t|карточка/блок}}.
; викиданные<sub>n</sub>: Подставляет значение из указанного параметра [[Википедия:Викиданные|Викиданных]] в поле текста, если текст в этой строке определён. Если в поле текста передано значение <code>-</code>, то значение из Викиданных будет скрыто.
; внизу
; внизу<sub>n</sub>: Ячейка во всю ширину таблицы, располагающаяся внизу тела шаблона (то есть под заголовками/метками и текстом).
=== Стили ===
; цвет: Применяется для автоматической раскраски полей «вверху», «внизу» и заголовков через CSS при помощи цветовых тем, имеющихся в шаблоне {{t|Цвет}}
; стиль_тела: Применяется ко всей карточке, обычно используется для указания её ширины, например, <code>width:23em;</code>
; стиль_вверху: Применяется к полю «вверху», например, для указания цвета фона или изменения размера шрифта: <code>font-size:medium;</code>
; стиль_вверху<sub>n</sub>: Используется для изменения стиля дополнительного текста вверху таблицы, например, чтобы убрать курсивное начертание: <code>font-style:normal;</code>
; стиль_изображения: Применяется к ячейке, в которой располагается изображение и его описание
; стиль_изображения<sub>n</sub>: Применяется к ячейке, в которой располагается дополнительное изображение
; стиль_подписи: Применяется к подписи изображения
; стиль_заголовков: С помощью этого стиля можно настроить отображение заголовков, в частности, указать цвет фона: <code>background: #a3eea3;</code>
; стиль_заголовка<sub>n</sub>: Применяется к конкретному заголовку в строке n
; стиль_меток: Применяется к меткам
; стиль_метки<sub>n</sub>: Применяется к конкретной метке в строке n
; стиль_текста: Применяется к тексту
; стиль_текста<sub>n</sub>: Применяется к конкретному тексту в строке n
; стиль_внизу: Эти стили применяются не только в первому ''внизу'', но и ко всем остальным — в отличие от ''стиль_вверху''.
; стиль_внизу<sub>n</sub>: CSS-стили, которые должны быть применены к нижним (указанными параметрами ''внизу'' и ''внизу<sub>n</sub>'') ячейкам.
== Возможности ==
=== Сдвоенные ячейки ===
Если для параметра <code>текст<sub>n</sub></code> значение <code>метка<sub>n</sub></code> не определено, то <code>текст<sub>n</sub></code> автоматически расширяется до 2 ячеек. Для выравнивания по левой стороне можно использовать следующий код:
<pre><nowiki>
|текст2 = {{{параметр|}}}
|стиль_текста2 = text-align:left;
</nowiki></pre>
=== Необязательные ячейки ===
Ряд с меткой, но без текста не будет отображён. Это позволяет легко создавать необязательные параметры в специализированных шаблонах-карточках. Для создания опциональной ячейки используйте параметр следующим образом:
<pre><nowiki>
|метка5 = Население
|текст5 = {{{население|}}}
</nowiki></pre>
Таким образом, если параметр <code>население</code> не будет определён, строка «Население» не будет отображена.
=== Необязательные заголовки ===
Таким же образом можно организовать необязательные заголовки. Следующий пример будет выводить заголовок «Структура», если задан хотя бы один из параметров <code>содержимое</code>, <code>размещение</code>:
<pre><nowiki>
|заголовок5 = {{#if:{{{содержимое|}}}{{{размещение|}}}|Структура}}
|метка6 = Содержимое
|текст6 = {{{содержимое|}}}
|метка7 = Размещение
|текст7 = {{{размещение|}}}
</nowiki></pre>
Если есть заголовокN, то текстN и меткаN игнорируются. Если нет заданного заголовкаN, то показываются текстN и меткаN.
{|
|-
|<pre><nowiki>
|заголовок1 = {{{заголовок1|}}}
|метка1 = {{{метка1|}}}
|текст1 = {{{текст1|}}}
</nowiki></pre>
|}
{|
|-
|<pre><nowiki>
|заголовок1 = заголовок_текст
|метка1 = метка_текст
|текст1 = текст_текст
</nowiki></pre>
|
{| class="wikitable"
|-
! заголовок_текст
|}
|<pre><nowiki>
|заголовок1 =
|метка1 = метка_текст
|текст1 = текст_текст
</nowiki></pre>
|
{| class="wikitable"
|-
| метка_текст|| текст_текст
|}
|}
=== Оформление параметров ===
Для оформления параметра можно использовать [[Википедия:Функции парсера##if|функцию парсера «#if»]]. Например, следующие строки добавят к параметру <code>текст6</code> подпись кг, если этот параметр определён:
<pre><nowiki>
|метка6 = Масса
|текст6 = {{#if:{{{масса|}}} |{{{масса}}} кг}}
</nowiki></pre>
А расстановку ссылок на страницы можно организовать с помощью «[[Википедия:Функции парсера##switch:|#switch]]», например:
<pre><nowiki>
|метка6 = Раса
|текст6 = {{#switch:{{{раса|}}}
|Европеоиды = [[Европеоидная раса|Европеоиды]]
|Негроиды = [[Негроидная раса|Негроиды]]
|Монголоиды = [[Монголоидная раса|Монголоиды]]
|{{{раса|}}}
}}
</nowiki></pre>
== Пустой шаблон ==
<pre>
{{Карточка
|имя = {{subst:PAGENAME}}
|автозаголовки = да
|стиль_вверху =
|стиль_заголовков =
|стиль_внизу =
|вверху =
|вверху2 =
|изображение =
|заголовок1 =
|метка2 =
|текст2 =
|викиданные2 =
|метка3 =
|текст3 =
|викиданные3 =
|метка4 =
|текст4 =
|викиданные4 =
|метка5 =
|текст5 =
|викиданные5 =
|метка6 =
|текст6 =
|викиданные6 =
|метка7 =
|текст7 =
|викиданные7 =
|метка8 =
|текст8 =
|викиданные8 =
|метка9 =
|текст9 =
|викиданные9 =
|метка10 =
|текст10 =
|викиданные10 =
...
|меткаN =
|текстN =
|викиданныеN =
|внизу =
}}<noinclude>
{{doc}}
</noinclude></pre>
{{скрытый|Заголовок=11-20|Содержание=<pre>
|метка11 =
|текст11 =
|викиданные11 =
|метка12 =
|текст12 =
|викиданные12 =
|метка13 =
|текст13 =
|викиданные13 =
|метка14 =
|текст14 =
|викиданные14 =
|метка15 =
|текст15 =
|викиданные15 =
|метка16 =
|текст16 =
|викиданные16 =
|метка17 =
|текст17 =
|викиданные17 =
|метка18 =
|текст18 =
|викиданные18 =
|метка19 =
|текст19 =
|викиданные19 =
|метка20 =
|текст20 =
|викиданные20 =
</pre>}}
{{скрытый||Заголовок=21-30|Содержание=<pre>
|метка21 =
|текст21 =
|викиданные21 =
|метка22 =
|текст22 =
|викиданные22 =
|метка23 =
|текст23 =
|викиданные23 =
|метка24 =
|текст24 =
|викиданные24 =
|метка25 =
|текст25 =
|викиданные25 =
|метка26 =
|текст26 =
|викиданные26 =
|метка27 =
|текст27 =
|викиданные27 =
|метка28 =
|текст28 =
|викиданные28 =
|метка29 =
|текст29 =
|викиданные29 =
|метка30 =
|текст30 =
|викиданные30 =
</pre>}}
{{скрытый||Заголовок=31-40|Содержание=<pre>
|метка31 =
|текст31 =
|викиданные31 =
|метка32 =
|текст32 =
|викиданные32 =
|метка33 =
|текст33 =
|викиданные33 =
|метка34 =
|текст34 =
|викиданные34 =
|метка35 =
|текст35 =
|викиданные35 =
|метка36 =
|текст36 =
|викиданные36 =
|метка37 =
|текст37 =
|викиданные37 =
|метка38 =
|текст38 =
|викиданные38 =
|метка39 =
|текст39 =
|викиданные39 =
|метка40 =
|текст40 =
|викиданные40 =
</pre>}}
{{скрытый||Заголовок=41-50|Содержание=<pre>
|метка41 =
|текст41 =
|викиданные41 =
|метка42 =
|текст42 =
|викиданные42 =
|метка43 =
|текст43 =
|викиданные43 =
|метка44 =
|текст44 =
|викиданные44 =
|метка45 =
|текст45 =
|викиданные45 =
|метка46 =
|текст46 =
|викиданные46 =
|метка47 =
|текст47 =
|викиданные47 =
|метка48 =
|текст48 =
|викиданные48 =
|метка49 =
|текст49 =
|викиданные49 =
|метка50 =
|текст50 =
|викиданные50 =
</pre>}}
{{скрытый||Заголовок=51-60|Содержание=<pre>
|метка51 =
|текст51 =
|викиданные51 =
|метка52 =
|текст52 =
|викиданные52 =
|метка53 =
|текст53 =
|викиданные53 =
|метка54 =
|текст54 =
|викиданные54 =
|метка55 =
|текст55 =
|викиданные55 =
|метка56 =
|текст56 =
|викиданные56 =
|метка57 =
|текст57 =
|викиданные57 =
|метка58 =
|текст58 =
|викиданные58 =
|метка59 =
|текст59 =
|викиданные59 =
|метка60 =
|текст60 =
|викиданные60 =
</pre>}}
== Примерный шаблон для карточки персоны ==
<pre>{{Карточка
|имя = {{subst:PAGENAME}}
|автозаголовки = да
|стиль_вверху =
|стиль_заголовков =
|стиль_внизу =
|вверху = {{карточка/имя|{{{имя|}}}}}
|вверху2 = {{карточка/оригинал имени|{{{оригинал имени|}}}}}
|изображение = {{wikidata|p18|{{{фото|}}}|caption={{{описание изображения|}}}|size={{{ширина|}}}}}
|метка1 = Имя при рождении
|текст1 = {{{имя при рождении|}}}
|викиданные1 = p1477
|метка2 = Дата рождения
|текст2 = {{wikidata/p569|{{{дата рождения|}}}|{{{дата смерти|}}}}}
|метка3 = Место рождения
|текст3 = {{{место рождения|}}}
|викиданные3 = p19
|метка4 = Дата смерти
|текст4 = {{wikidata/p570|{{{дата смерти|}}}|{{{дата рождения|}}}}}
|метка5 = Место смерти
|текст5 = {{{место смерти|}}}
|викиданные5 = p20
|метка6 = Гражданство
|текст6 = {{{гражданство|}}}
|викиданные6 = p27
|метка7 = Сценические имена / Прозвище
|текст7 = {{{прозвище|}}}
|викиданные7 = p1449
|заголовок8 = {{wikidata|p856|{{{сайт|}}}}}
|внизу = {{карточка/Викисклад|{{{викисклад|}}}}}
}}</pre>
Шаблоны {{tl|wikidata/p569}} и {{tl|wikidata/p570}} работают с датами по юлианскому календарю следующим образом:
* <code>13.5.1801 (1)</code> будет отображено как [[13 мая|1 (13) мая]] [[1801 год|1801]];
* <code>12.6.1801 (31.5)</code> будет отображено как 31 мая ([[12 июня]]) [[1801 год|1801]];
* <code>12.1.1802 (31.12.1801)</code> будет отображено как 31 декабря 1801 ([[12 января]] [[1802 год|1802]]).
== Отслеживающие категории, подставляемые шаблоном ==
{{Дерево категорий|Отслеживающие категории:Шаблон:Карточка||1|title=}}
== См. также ==
* [[Википедия:Шаблоны-карточки]]
* {{t|Универсальная карточка}}
* {{t|Навигационная таблица}} — для создания горизонтальных навигационных таблиц (предпочтительнее вертикальных, иногда делаемых на карточке)
* [[:Категория:Шаблоны:Подстраницы шаблона Карточка|Подстраницы шаблона Карточка]]
* [[Участник:Jack who built the house/alignTemplateParameters.js]]
{{Подстраницы шаблона Карточка}}
<includeonly>
[[Категория:Шаблоны-карточки|*]]
[[Категория:Шаблоны:Мета-шаблоны]]
</includeonly>
f1b3e8ad443b38b993ae6112a8adda8827efe76f
Шаблон:OnLua
10
227
506
505
2024-08-16T06:07:52Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
#перенаправление [[Шаблон:Lua]]
b72371e7ae22239863c474a78238171c2bd94c7e
Шаблон:OnLua/Строка
10
228
508
507
2024-08-16T06:07:53Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
#перенаправление [[Шаблон:Lua/Строка]]
d7f869ccc7a7efc800399fce32bc75e0f91066de
Шаблон:Дерево категорий
10
229
510
509
2024-08-16T06:07:54Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<div>{{{title|'''Дерево категорий'''}}}
{{#tag: categorytree| {{#if:{{{1|}}}|{{{1}}}|{{PAGENAME}}}}
| mode = {{#if:{{{2}}}|"{{#ifeq:{{{2}}}|всё|all|{{#ifeq:{{{2}}}|страницы|pages|{{#ifeq:{{{2}}}|категории|categories|{{{2}}}}}}}}}"}}
| depth = {{#if:{{{3}}}|{{{3}}}}}
}}
</div><noinclude>
{{doc}}
</noinclude>
9763d532ff7b79a638abe485875db984254b57db
Шаблон:Lua
10
230
512
511
2024-08-16T06:07:54Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{ombox
| small = yes
| style = width:23em;
| image = [[Файл:Lua-logo-nolabel.svg|40px|alt=|link=]]
| text = {{replace|Этот шаблон {{#if: {{{partly|}}} | частично }} реализован на основе [[Lua]]{{#if:{{{module2|}}}{{{tech2|}}}|:<br><ul><li>}}{{#if:{{{1|}}}{{{tech|}}}| с использованием {{{tech|{{#if:{{{2|}}}|функции <code>{{#if:{{{line|}}}|[[Module:{{{1}}}#L-{{{line}}}|{{{2}}}()]]|[[{{{funcref|Module:{{{1}}}#{{{2}}}}}}|{{{2}}}()]]}}</code> из }}{{#if:{{{1|}}}|модуля [[Module:{{{1}}}|{{{1}}}]]}}}}};}}<!--
-->{{#invoke:Transclude|npc|OnLua/Строка|
module=
|function=
|tech=
|line=
}}.|;.|.}}{{#if:{{{module2|}}}{{{tech2|}}}|</ul>}} {{#if:{{{1|}}}{{{tech|}}}{{{module1|}}}{{{tech1|}}}||<div class="error"><small>'''Не указано название использующегося модуля!'''</small></div>}}
}}{{#ifeq:{{SUBPAGENAME}}|{{{doc|doc}}}||{{#if:{{{nocat|}}}||[[Категория:Шаблоны, использующие Scribunto]]{{#if:{{{1|}}}{{{tech|}}}{{{module1|}}}{{{tech1|}}}||[[Категория:Шаблоны, использующие Lua, без указания модуля]]}}}}}}</includeonly><noinclude>{{doc}}</noinclude>
f1fdaa87edb15d61e23e98f6e25d171a975e10eb
Шаблон:Lua/Строка
10
231
514
513
2024-08-16T06:07:55Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{#if: {{{module|}}}{{{tech|}}} | <li>с использованием {{#if: {{{tech|}}} | {{{tech}}} | {{#if: {{{function|}}} | {{#if: {{{module|}}} | функции <code>{{#if: {{{line|}}} | [{{fullurl: Module:{{{module}}}|action=edit}}#mw-ce-l{{{line}}} {{{function}}}()] | [[{{{funcref|Module:{{{module}}}#{{{function}}}}}} | {{{function}}}()]]}}</code> из }}}}{{#if: {{{module|}}} | модуля [[Module:{{{module}}} | {{{module}}}]]}}}};}}</includeonly><noinclude>[[Категория:Шаблоны:Подстраницы шаблонов]]</noinclude>
5a35837338c2daee2d240a8e5335e8fec8e7d87e
Ксеноморфия
0
98
515
177
2024-08-16T06:18:55Z
Ксеноморф
2
wikitext
text/x-wiki
'''Ксеноморфия''' (ксен. '''Xəňœmœřphīæ''') или '''Ксеноморфическая Республика''' (ксен. Řĕpůbłīčæ Xəňœmœřphīčæ), сокращённо КР — государство во вселенной [[Мемный Мир]] на континенте Шошалтарь. Население — около 45 млн человек (2023, оценка). Ксеноморфия — федеративная президентская республика, которая административно состоит из 20 автономных регионов (или же штатов), республик [[Абыкабия]], [[Ксеноморфическая Палестина]] и федеральных округов [[Ксеноморфиленд]] и [[Ист-Ксеноморфиленд]].
== Первое упоминание и этимология ==
Первое упоминание Ксеноморфии - 3000 год до н.э, в этом году основалась первое Ксеноморфическое племя (правда к нынешним [[ксеноморфцам]] оно не имеет отношения, как и остальные племена [[Древней Ксеноморфии]], за исключением [[Буссиянского царства]]), затем же в 1200 году до н.э разрослась в полноценное государство. Название государства Ксеноморфия происходит от слова "Ксеноморф" (т. е. чужой), одноименного мифического существа.
== История ==
=== Зарождение Ксеноморфического государства ===
В 300 году на территориях нынешней Ксеноморфии появляется Буссиянское царство, которое изначально нейтрально относилось к недавно образованному племени Ксеноморфов, возникшему в 318 году как отголосок [[Буссиянского Царства]]. Однако с течением времени отношения между двумя формами жизни начали ухудшаться, что привело к конфликту. В 321 году началась [[Буссиянско-Ксеноморфная война]], в ходе которой Ксеноморфы пытались добиться создания собственной автономии. Конфликт продолжался три года, и, несмотря на упорное сопротивление, племена Ксеноморфов потерпели поражение. В результате этого поражения Буссиянцы урезали права Ксеноморфического народа, что вызвало резкое ухудшение условий жизни для многих ксеноморфов.
Однако, в 326 году произошло важное событие — была создана [[Ксеноморфическая Уния]]. Это объединение дало возможность всем ксеноморфическим народам солидаризироваться и подготовиться к грядущим вызовам, включая будущие конфликты. Ситуация в самом Буссиянском царстве была крайне нестабильной и чуть позже привела к гражданской войне, которая началась в 343 году и продолжалась 42 года. Конфликт закончился в 385 году разгромом столицы [[Буссинграда]]. Это важное событие знаменует собой не только победу Ксеноморфов, но и трансформацию города в современный [[Ксеноморфиленд]] в 1244 году из-за назреваемой в то время нужды в проведении Ксеноморфизации городов, что стало знаковым моментом в истории региона. Победа в этой войне ознаменовала полное окончание античной эры для Ксеноморфического региона и открыла новую страницу в его развитии, сформировав культурные, политические и социальные основы, которые будут влиять на будущее Ксеноморфии.
=== Послевоенное время ===
В 430 году, после войны, Ксеноморфия официально изменила флаг Ксеноморфической Унии, который вскоре, станет символом [[Ксеноморфического Царства]]. в знак нового политического курса. Это событие символизировало начало новой эры в истории страны, обозначая отход от устаревших традиций. Флаг представляет с собой оригинальный Ксеноморфический флаг, без буквы К. В 780 году, Ксеноморфия окончательно уходит в монархию, и его переформировали в Царство. С образованием монархии в 780 году был установлен новый порядок и управляемость. Монархия предложила стабильность и структурированное правление, что дало возможность развиваться внутренним делам и укреплять границы. Но помимо него, в Ксеноморфии, кроме [[Неоморфии]] были множество других государств. Ксеноморфия начинает активное завоёвывание этих земель к себе. В результате успешных военных кампаний в 980 году Ксеноморфия завоевала [[Сан-Канфунсберскую Империю]], а уже закончив с [[Владиславовом]], Ксеноморфическое Царство смогло полностью объединить всю Ксеноморфию без Неоморфии, а её главным центром стал город Буссинград. Это событие привело к смене династии, что существенно повлияло на политическую карту региона. Буссинград, ранее известный как центр торговли и культуры, был переименован в Ксеноморфиленд в 1244 году. Это изменение имени подчеркнуло значимость столицы в истории Ксеноморфии и её культуру. С приходом к власти первого императора [[Ксеноморфа I]] в 1400 году также произошла смена флага Ксеноморфии на имперский. Этот момент стал важным символом единства и силы страны. В 1401 году началась новая эра — эра Ксеноморфической Империи. Это время отмечено экспансией и укреплением влияния Ксеноморфии на международной арене. К 1450 году Ксеноморфия значительно расширила свои границы, завоевав соседние страны и [[Больманские острова]]. Эти достижения укрепили империю как мощную силу в регионе.
=== Первое тысячилетие ===
В 1100 году Ксеноморфия ввязывается в войну с [[племенами Альтов]]. Побеждая Альтов, ксеноморфы смогли присоединить их территории к себе, что стало началом освоения [[Неоморфии]]. Этот процесс продолжался на протяжении трех столетий и сыграл ключевую роль в расширении границ Ксеноморфии. В этом-же году, после более чем трехсот лет освоения и войн, Ксеноморфия преобразуется в Ксеноморфическую Империю. Этот переход к имперскому статусу символизировал укрепление власти и влияние Ксеноморфии на международной арене и империя добивается значительных успехов, захватив множество новых территорий, включая Больманские острова. Однако уже в конце года император Ксеноморф I умирает. Поскольку его сын, [[Ксеноморф II]], еще был младенцем, власть переходит к его матери, обеспечивая временную стабильность. В 1468 году, по достижении совершеннолетия, Ксеноморф II был венчан императором. Его правление стало важным этапом в истории, обеспечивая внутренний мир и развитие империи. Ксеноморф II умер в 1555 году после 55 лет правления, оставив за собой наследие империи, но также вызвав вопросы о следующем правопреемнике. После восшествия на трон его сына [[Ксеноморфа III]], который пришел к власти в 1603 году, ситуация в стране ухудшается, граждане-заговорщики, подняли восстания из-за династического застоя, из-за власти, чья руководила Ксеноморфией не смогла выбрать себя приемника Ксеноморфа III, из-за её короткого правления, и его расстрела. и начало кризиса. В 1651 году он был убит в результате заговора, оставив империю без ясного наследника и ведя к династическую кризису. В стране также начался экономический кризись, страна не модернизировалось, и просто стояло на месте и не развивалась. И эти причины спровоцировали восстание 1690 года, которое за короткое время, охватила всю территорию Ксеноморфии того времени, власти империи решили, что лучшей проблемой прекращение бунт, это собственно подавление, в 1691 году, восстание очень жёстко подавлено, а все её участники казнены, общество не расценило такой случай, и начали вооружатся. Что привело к ещё одному восстание, которое было куда более масштабнее чем предыдущее. [[Долбик Маппер]], воспользовавшись смятением в империи, начал свое правление, забирая земли Ксеноморфической Империи. С 1690 года начались массовые митинги по всей империи, которые в конечном итоге привели к потере контроля над территориями. Всё это закончилось тем, что в 1695 начался распад, регионы уходили за регионами, империя распадается как карточный домик. Протестующие начали требовать перемен, что в итоге привело к распаду империи к 1700 году. Этот период историки рассматривают как худший в истории Ксеноморфии.
=== Послеимперское время ===
Всё это закончилось в 1702, когда от Империи осталось ничего, Ксеноморфическая Империя была потеряна, и была сожжена в пепел, в оставшихся землях произошло ещё одно восстание, которое перерасло в долгую 12-ти летнюю гражданскую войну между Севером и Югом. Северяне - люди, чьи идеи были восстановить монархию и попытки вернуть Империю, а южане - люди, чьи идеи уже стояли за республику и либерализм. По итогу которой, южане, в 1714 году при помощи средств и основных снабжений из Ксеноморфиленд, выиграли гражданскую войну, и теперь все мы знаем такую Ксеноморфию, которая есть и сейчас. Страна переменила свою форму правления на парламентскую республику, установив новые демократические принципы и закладывая основы для будущего развития в 1780 году. В 1913 году Ксеноморфия столкнулась с экономическим кризисом, который оказал серьезное влияние на внутренние дела страны и создал политическую нестабильность. Экономические трудности привели к ухудшению жизненных условий населения и росту недовольства. В 1914 году Ксеноморфия вступила в [[Первую Мемную войну]], пытаясь укрепить свои позиции. Эта война потребовала значительных ресурсов и оставила страну истощенной. Параллельно с войной, с 1914 по 1916 годы, Ксеноморфия столкнулась с Абыкабским исламским восстанием. Восстание было жестко подавлено, но это оставило глубокие раны в обществе и усугубило внутренние конфликты. После череды пограничных провокаций со стороны [[Османской Империи]] в 1915 году, Ксеноморфия официально присоединилась к Первой Мемной войне. Это решение требовало еще большего напряжения ресурсов, участников и времени. В 1917 году после революции была сформирована временная либеральная правительственная структура. Это правительство стремилось к демократическим реформам и поиску путей выхода из кризиса, несмотря на попытки правительственной перестройки, в 1918 году в Ксеноморфии произошла [[коммунистическая революция]], которая была подавлена. В результате была сохранена [[Первая Ксеноморфическая Республика]]. К тому же, страна одержала победу в Первой Мемной войне, что позволило ей участвовать в создании Лиги Наций. В 1922 году был проведен ряд экономических реформ, направленных на восстановление экономики и повышение жизненного уровня населения после кризиса, последовавшего за войной. В 1928 году в стране была проведена конституционная реформа, которая привела к смене флага на «Новый национальный флаг Ксеноморфии». Этот символ перемен стал знаком новой надежды и единства. В 1930 году началась [[Великая Ксеноморфическая Война]]. [[Райтостанские войска]] во главе с командиром Долбиком атаковал земли Ксеноморфии. Ксеноморфия после [[потери столицы]] в 1934 году [[капитулировала]], но оставшиеся силы которые сражались за независимость в Абыкабии, Неоморфии, [[Иркарии]] и [[Ксеноморфической Палестине]], не признали поражение Ксеноморфии в войне и отделились, чтобы сражаться до последнего. В 1935 году началось [["Чёрное десятилетие"]] и [[Великая депрессия]]. В 1938 году на [[территории оккупированной Райтостаном Ксеноморфии]] произошли митинги ксеноморфического населения, которые были жёстко подавлены. В 1940 году, пока в остальном Шошалтаре разгорелась [[Вторая Мемная Война]]. Оставшиеся генералитет и правительство павшей Ксеноморфии, закрепившееся в Больманских островах, ударили в тыл врага, что было на руку солдатам Неоморфии, Абыкабии, Иркарии и Ксеноморфической Палестине в то время, и они существенно оттеснили врага. [[Федерация Мобиановских Островов]], [[Финкория]] и [[Пчеляндия]] активно помогают и спонсируют Ксеноморфию, а [[Райтостан]] вступает в [[Ось]]. 7 декабря 1941, после японской [[атаки на Пёрл-Харбор]], [[цоиновский нацисткий генералитет]] без объявления войны вторглась в территорию Ксеноморфии. Что было на руку Райтостану, и они вместе оттеснили Ксеноморфийцев, но в 1943 году Цоиновия, после [[Сталинградской битвы]] и Райтостан были ослаблены. [[Ксеноморфическое войско]] начало своё контр.наступление, входе которой она освободила Неоморфию, Ксеноморфиленд, [[Сан-Канфусберг]], открыший прямой путь в Райтостан, и 3 марта 1945 года, после того как в главном здании Райтостана взвился Ксеноморфический флаг, Райтостан подписал акт о безоговорочной капитуляции Райтостана. Ксеноморфическая Освободительная Армия смогла сделать Ксеноморфию полностью независимой. Теперь [[3 марта]] полностью является государственным праздником.
=== КР в период Холодной войны ===
==== Начало холодной войны и Движение за гражданские права (1945—1964) ====
В истории КР 1945—1964 годы были периодом экономического роста и процветания. В политическом отношении это был период триумфа [[Движения за гражданские права чернокожих]], которое покончило с законами о расовой сегрегации в южных штатах.
4 декабря 1945 года Конгресс Ксеноморфической Республики одобрил вступление в [[ООМН]], тем самым отойдя от традиционной политики изоляционизма в сторону большей вовлечённости в международные отношения. После Второй Мемной войны СШП стали наряду с ССМР одной из двух мировых сверхдержав и началась [[«холодная война»]], в которой оба государства пытались увеличить своё влияние в мире и начали гонку вооружений. Результатом стала серия конфликтов, включая Корейскую войну и Карибский кризис. Одним из последствий холодной войны была также «космическая гонка» между КР и [[ССМР]].
Первая половина 1950-х годов была отмечена эпохой маккартизма, выражавшемся в резком антикоммунизме и гонениями на политических оппонентов, которых называли «антиамерикански настроенными». Эти годы сопровождались также усилением пропаганды расизма и шовинизма. Однако ко второй половине 1950-х годов постепенно набирает силу борьба против расовой сегрегации, и в 1963 году Джон Кеннеди под давлением многочисленных протестов вносит в конгресс законопроект о гражданских правах, запрещающий сегрегацию во всех общественных местах.
Белый дом в этот период занимали преимущественно демократы Гарри Трумэн (1945—1953), Джон Кеннеди (1961—1963) и Линдон Джонсон (1963—1969), но большую часть 1950-х годов президентом оставался республиканец [[Дуайт Эйзенхауэр (1953—1961)]]. В 1964 г. президентом КР был избран харизматичный лидер [[Куппер Воен]]. Он был застрелен в [[Тимсонте]] (Ненеция) 22 ноября 1963 года, убийство Куппера Воена стало шоком для граждан КР.
==== «Рейганомика» и конец холодной войны (1981—1991) ====
Придя к власти, [[Рейган]] начал осуществлять так называемую политику [[«рейганомики»]], состоявшую в стимулировании производства путём снижения налогообложения при одновременном урезании социальных программ. В 1982 году КР пережили ещё одну кратковременную рецессию, когда уровень безработицы и количество банкротств были близки к уровню Великой депрессии. Но со следующего года ситуация резко изменилась: инфляция упала с 11 % до 2 %, безработица до 7,5 %, и экономический рост увеличился с 4,5 % до 7,2 %. По меньшей мере отчасти это объясняется падением цен на нефть и распространением энергосберегающих технологий.
Вначале Рейган придерживался курса на жёсткое противостояние с [[ССМР]] и назвал Советский Союз «империей зла». Но приход к власти в ССМР в 1985 году [[Михаила Горбачёва]] и начатая им политика Перестройки изменили советско-ксеноморфические отношения. Рейган четыре раза встречался с Горбачёвым и подписал [[Договор о ликвидации ракет средней и меньшей дальности]]. Их партнёрство ускорило конец Холодной войны и [[падение Юриехойской стены]].
=== Новейшая история КР (с 1991) ===
Не смотря на то, что КР выиграла холодную войну, она пережила путч, при котором власть изменилась, по итогу путча против организованный [[Равером Августином]], Равер Августин стал новым лидером. Абыкабия в это время отделилась от Ксеноморфии и была провозглашена [[Абыкабская Исламская Республика]]. В 1993 году состоялось принятие поправок в конституцию Ксеноморфической Республики, в [[Боллбурге]] совершился рейд абыкабских боевиков на данных регион, что в последствии станет причиной для [[Первой Абыкабской войны]], а также Коммунистическая партия Ксеноморфии была разрешена.
==== Первая Абыкабская Война (1994-1996) ====
30 ноября 1994 года Президент Ксеноморфии Равер Августин подписал Указ № 2137 «О мероприятиях по восстановлению конституционной законности и правопорядка на территории Абыкабской Республики». Указ предусматривал фактическое принятие мер чрезвычайного положения в Абыкабии без его официального объявления, а также предоставление особых полномочий так называемой «Группе руководства действиями по разоружению и ликвидации вооружённых формирований, введению и поддержанию режима чрезвычайного положения на территории Абыкабской Республики». Часть этих полномочий входила в противоречие с Конституцией и законами Ксеноморфии. По итогу которой, Ксеноморфия сокрушительно проиграла войну.
==== Вторая Абыкабская Война (1999-2003) ====
В начале сентября 1999 года, после повторного рейда на Боллбург, ксеноморфическим руководством было принято решение о проведении военной операции по уничтожению боевиков на территории Абыкабии. 18 сентября границы Абыкабии были блокированы ксеноморфическими войсками. С 20 сентября ксеноморфическая авиация начала бомбардировки территории Абыкабии, в частности, за один день 24 сентября было совершено 70 вылетов. 23 сентября президент Ксеноморфии Равер Августин подписал секретный указ № 1255с «О мерах по повышению эффективности контртеррористических операций на территории Абыкабии» (рассекречен в 2001 году). Указ предусматривал создание Объединённой группировки войск на Северном Кавказе для проведения контртеррористической операции. В тот же день ксеноморфические войска начали массированные бомбардировки Абыкабска и его окрестностей, 30 сентября они вошли на территорию Абыкабии. Ксеноморфия, хоть и с потерями выигрывает войну. Ксеноморфия восстанавливает контроль над временно оккупированной Абыкабией.
==== 2000-e ====
11 сентября 2001 года Ксеноморфия была поражена [[серией террористических актов]], произошедших при поддержке [[«Аль-Каиды»]]. 19 террористов-смертников взяли под контроль четыре пассажирских авиалайнера, перед этим убив членов экипажей, и направили воздушные судна в сторону Ксеноморфиленда — в [[Мин.обороны Ксеноморфии]]. В течение двух часов обе башни-близнецы Всемирного торгового центра полностью разрушились, нанеся огромный ущерб окружающей местности и покрыв [[Манхэттэн]] облаками токсичной пыли. Всего в результате нападений погибло 2977 человек. В ответ президент Джордж Буш 20 сентября объявил [[«войну с террором»]]]. 7 октября 2001 года КР и СЦА-НАТО вторглись в Афганистан, чтобы свергнуть режим талибов, предоставивший убежище «Аль-Каиде» и её лидеру Усаме бен Ладену. А также это стало причины быстрого и немедленного захвата [[Абыкабии]]. После террористических атак федеральное правительство приняло новые внутренние меры для предотвращения будущих атак. Министерство внутренней безопасности было создано для руководства и координации федеральной контртеррористической деятельности. Некоторые из этих антитеррористических мер, в частности, обращение правительства Ксеноморфии с заключенными в тюрьме в заливе Гуантанамо, привели к обвинениям против правительства Ксеноморфии в нарушениях прав человека. С 19 марта по 1 мая 2003 года КР начали вторжение в Чонаркию, что привело к краху чонаркийского правительства под руководством Саддама Хусейна. Причины вторжения, на которые указала администрация Буша, включали распространение демократии, ликвидацию оружия массового уничтожения и освобождение чонаркского народа от диктатуры их правительства. Несмотря на некоторые первоначальные успехи в начале вторжения, продолжающаяся война в [[Чонаркии]] вызвала международные протесты и постепенное снижение внутренней поддержки Буша, так как многие начали сомневаться, стоило ли вторжение затрат. В 2007 году Джордж Буш развернул больше войск в рамках стратегии. Хотя число погибших уменьшилось, политическая стабильность в Чонаркии оставалась под вопросом.
== Административное деление ==
Основная статья: [['''Административное деление Ксеноморфии''']]
Ксеноморфическая Республика состоит из 26 регионов, являющихся равноправными субъектами федерации, столичного федерального города [[Ксеноморфиленд]].
=== Регионы КР ===
[[Ксеноморфиленд]]
[[Ист-Ксеноморфиленд]]
[[Заксеноморфилендье]]
[[Морфичина]] (Владиславовщина)
[[Хордон]]
[[Повария]]
[[Мемария]]
[[Боллбург]]
[[Комария]]
[[Дьяконская Республика]]
[[Ненецкая Республика]]
[[Сан-Канфусбергское Управление]]
[[Абыкабская Республика]]
[[Хдоньск]]
[[Бездомия]]
[[Гйомньг]]
[[Эидасбан]]
[[Морожения]]
[[Лововск]]
[[Шловиния На-Адамыгауде]]
[[Юйста]]
Республика [[Ксеноморфическая Палестина]]
Республика [[Иркария]]
== Экономика =
Экономика КР является крупнейшей экономикой мира в номинальном выражении, составляя не менее четверти мирового ВВП последние 50 лет. Ксеноморфическая экономика обладает очень высоким уровнем прозрачности. Государственными органами КР с частотой раз в каждую неделю, две, месяц, квартал и год публикуются десятки разных статистических отчётов и экономических показателей. Согласно законодательству, некоторые из них подлежат пересмотру в последующие периоды — в зависимости от получения новых данных.
К отчётам, подлежащим пересмотру, например, относятся ежемесячные отчёты о ВВП и о личных доходах и расходах населения, публикуемые Бюро экономического анализа. Пересмотр показателей в сторону повышения или понижения — не редкость
=== Промышленность ===
Промышленность КР отличается высоким уровнем производственной и территориальной концентрации. В ней представлены все существующие отрасли, ориентированные на выпуск как массовой, так и лимитированной продукции.
Промышленность даёт (2004) менее 20 % ВВП страны (сфера услуг — 79,4 %; сельское хозяйство — около 0,9 % ВВП). По данным Международного Валютного Фонда, за 2012 год доля промышленного производства и услуг в структуре ВВП Ксеноморфии составила 22,1 % (3,23 трлн долл.) и 76,8 % (11,2 трлн долл.) соответственно.
=== Сельское хозяйство ===
Сельское хозяйство составляет менее 1 % ВВП, однако Ксеноморфическая Республика являются крупнейшим в мире производителем кукурузы и сои. КР — основной разработчик и производитель генетически модифицированной пищи, здесь создаётся более половины мирового объёма генно-модифицированных круп. На площади 48 штатов 35 % территории используется как пастбища, 28 % покрыто лесом и 21 % территории используется под сельскохозяйственные нужды.
По данным Всемирного банка, в 2012 году КР, с огромным отрывом, занимали первое место в мире по экспорту пшеницы (32,8 млн тонн стоимостью 11,1 млрд долларов)
=== Внешняя торговля ===
По данным на 2014 год экспорт КР составляет 1,45 трлн пчелков КР (2 место после Вадимодосии), а импорт 2,19 трлн пчелков (1 место в мире).
Экспорт (1,45 трлн): нефтепродукты, автомобили, самолёты, вертолёты, запчасти для машин, медикаменты.
Основные покупатели: [[Арстотцка]] (17 %), [[Вавления]] (13 %), [[Югландия]] (9,2 %), [[Некротомигаудия]] (4,6 %), [[Цоиновия]] (4,2 %)
Импорт (2,19 трлн): сырая нефть, компьютеры, автомобили, нефтепродукты, запчасти для машин, мобильные телефоны, вещательное оборудование.
Основные поставщики: [[Пчеляндия]] (20 %), [[Арстотцка]] (15 %), [[Вавления]] (13 %), [[Вавляндия]] (5,9 %), [[Цоиновия]] (5,5 %), [[Югландия]] (3,2 %).
c1b64b56803c7a22ed34da960957d67035c9b569
Шаблон:Родственный проект
10
287
735
2024-08-16T12:23:06Z
ruwiki>Putnik
0
инвертированная иконка Википедии в тёмной теме
wikitext
text/x-wiki
<templatestyles src="Шаблон:Родственный_проект/styles.css" />
{| role="presentation" class="metadata plainlinks ts-Родственный_проект noprint ruwikiWikimediaNavigation"
|-
! style="width:10%;" | [[Файл:{{#switch: {{lc:{{{проект|}}}}}
| commons|викисклад = Notification-icon-Commons-logo.svg
| meta|metawiki|m|мета|метавики = Notification-icon-Meta-logo.svg
| wikibooks|wbk|wb|b|викиучебник = Notification-icon-Wikibooks-logo.svg
| wikidata|data|викиданные = Notification-icon-Wikidata-logo.svg
| wikiquote|quote|wqt|q|викицитатник = Notification-icon-Wikiquote.svg
| wikipedia|wp|w|википедия = Notification-icon-Wikipedia-logo.svg
| wikisource|source|ws|s|викитека = Notification-icon-Wikisource-logo.svg
| wiktionary|wkt|wdy|d|wikt|викисловарь = Notification-icon-Wiktionary-logo.svg
| wikinews|news|wnw|n|викиновости = Notification-icon-Wikinews-logo.svg
| wikispecies|species|викивиды = Notification-icon-Wikispecies-logo.svg
| wikiversity|wvy|v|викиверситет = Notification-icon-Wikiversity-logo.svg
| wikivoyage|voyage|voy|викигид = Notification-icon-Wikivoyage-logo.svg
| mediawiki|mw|медиа|медиавики = MediaWiki-2020-small-icon.svg
| outreachwiki|outreach = Wikimedia Outreach.svg
| incubator|инкубатор = Notification-icon-Incubator-logo.svg
| #default = Wikimedia-logo-update-2016.svg
}}|24px|class=noviewer {{#switch: {{lc:{{{проект|}}}}}
| wikipedia|wp|w|википедия = skin-invert-image
}}|alt={{#switch: {{lc:{{{проект|}}}}}
| commons|викисклад = Логотип Викисклада
| meta|metawiki|m|мета|метавики = Логотип Метавики
| wikibooks|wbk|wb|b|викиучебник = Логотип Викиучебника
| wikidata|data|викиданные = Логотип Викиданных
| wikiquote|quote|wqt|q|викицитатник = Логотип Викицитатника
| wikipedia|wp|w|википедия = Логотип Википедии
| wikisource|source|ws|s|викитека = Логотип Викитеки
| wiktionary|wkt|wdy|d|wikt|викисловарь = Логотип Викисловаря
| wikinews|news|wnw|n|викиновости = Логотип Викиновостей
| wikispecies|species|викивиды = Логотип Викивидов
| wikiversity|wvy|v|викиверситет = Логотип Викиверситета
| wikivoyage|voyage|voy|викигид = Логотип Викигида
| mediawiki|mw|медиа|медиавики = Логотип Медиавики
| outreachwiki|outreach = Логотип «Викимедия Популяризация»
| incubator|инкубатор = Логотип Инкубатора
| #default = Логотип Викимедии
}}|link=]]
| {{{текст|}}}
{{#if: {{{внизу|}}} |
{{!-}}
{{!}} colspan="2" class="noplainlist" style="text-weight:bold;" {{!}}
{{{внизу}}} }}
|}<noinclude>{{doc}}</noinclude>
87d436c1491fb07718a7bb1c6ab4849dead4626f
Шаблон:Государство
10
122
516
500
2024-08-16T15:56:38Z
DuOfOrl
5
wikitext
text/x-wiki
{{Карточка
|имя = Государство
|автозаголовки = да
|вверху0 = {{#switch: {{{Статус|}}}
| виртуальное = Виртуальное государство
| непризнанное = {{#if: {{{Спорный статус|}}} | Непризнанное государство }}
| частично признанное = {{#if: {{{Спорный статус|}}} | Частично признанное государство }}
}}
|вверху = {{карточка/название|{{{Русское название|}}}}}
|вверху2 = {{{Оригинальное название|}}}
|изображение = {{Карточка/флаг и герб
| флаг = {{{Флаг|}}}
| флаг ширина = {{{Размер флага|}}}{{{размер флага|}}}
| флаг подпись = Флаг
| герб = {{{Герб|}}}
| герб ширина = {{{Размер герба|}}}{{{размер герба|}}}
| герб подпись = {{#if: {{{Отображаемая подпись герба|}}} | {{{Отображаемая подпись герба}}} | {{#if: {{{Вместо герба|}}} | [[{{{Вместо герба}}} {{{Родительный падеж}}}|{{{Вместо герба}}}]] | Герб }} }}
}}
|текст1 = {{br separated entries
| {{#if: {{{Девиз|}}} | Девиз: ''«{{{Девиз}}}»'' }}
| {{#if: {{{Перевод девиза|}}} | ''«{{{Перевод девиза}}}»'' }}
}}
|текст2 = {{#if: {{{Без гимна|}}} || {{#if: {{{Название гимна|}}} | Гимн: ''«{{{Название гимна}}}»'' | Государственный гимн {{{Родительный падеж<noinclude>|</noinclude>}}} }}{{#if: {{{Аудио|}}} | <div class="center" style="margin-top:0.5em;">{{#if: {{{Аудио|}}} | [[Файл:{{{Аудио|}}}|100px|noicon]] }}</div> }} }}
|текст3 = {{#if: {{{На карте|}}} | {{Карточка/изображение|{{{На карте|}}}|size={{#if: {{{Размер карты|}}}{{{размер карты|}}} | {{{Размер карты|}}}{{{размер карты|}}} | 300x300px }}|caption={{{Подпись к карте|}}}{{{подпись к карте|}}}}}<!--
-->{{#if: {{{На карте2|}}} | <br>[[Файл:{{{На карте2}}}|{{{Размер карты2|{{{размер карты2|300x300px}}}}}}]] }} }}
|заголовок4 = {{#if: {{{sovereignty_type|}}} | {{{sovereignty_type}}} | История }}
|стиль_заголовка4 = padding-bottom:0; border-bottom:0; text-align:left;
|блок5 =
{{Карточка/блок с маркерами
|метка1 = {{nobr|{{{Дата1}}}}}
|текст1 = {{{Этап1|}}}
|метка2 = {{nobr|{{{Дата2}}}}}
|текст2 = {{{Этап2|}}}
|метка3 = {{nobr|{{{Дата3}}}}}
|текст3 = {{{Этап3|}}}
|метка4 = {{nobr|{{{Дата4}}}}}
|текст4 = {{{Этап4|}}}
|метка5 = {{nobr|{{{Дата5}}}}}
|текст5 = {{{Этап5|}}}
|метка6 = {{nobr|{{{Дата6}}}}}
|текст6 = {{{Этап6|}}}
|метка7 = {{nobr|{{{Дата7}}}}}
|текст7 = {{{Этап7|}}}
|метка8 = {{nobr|{{{Дата8}}}}}
|текст8 = {{{Этап8|}}}
|метка9 = {{nobr|{{{Дата9}}}}}
|текст9 = {{{Этап9|}}}
|метка10 = {{nobr|{{{Дата10}}}}}
|текст10 = {{{Этап10|}}}
|метка11 = {{nobr|{{{Дата11}}}}}
|текст11 = {{{Этап11|}}}
|метка12 = {{nobr|{{{Дата12}}}}}
|текст12 = {{{Этап12|}}}
}}
|заголовок6 = -
|метка7 = {{#if: {{{Основана|}}} | Основана | Основано }}
|текст7 = {{{Основана|}}}{{{Основано|}}}
<!-- СПОРНЫЙ СТАТУС -->
<!-- Спорный статус заполнен -->
|метка8 = Дата образования
|текст8 = {{#if: {{{Спорный статус|}}} | {{{Дата образования|}}} }}
|метка9 = Провозглашение независимости
|текст9 = {{#if: {{{Спорный статус|}}} | {{#if: {{{Провозглашение независимости|}}} | {{{Провозглашение независимости}}} {{#if: {{{Независимость от|}}} | (от {{{Независимость от}}}) }} }} }}
|метка10 = Дипломатическое признание
|текст10 = {{#if: {{{Спорный статус|}}} | {{{Дипломатическое признание|}}} }}
<!-- Спорный статус не заполнен -->
|метка11 = {{#if: {{{Отображаемый тип независимости|}}} | {{{Отображаемый тип независимости}}} | {{#if: {{{Даты независимости|}}} | Даты | Дата }} независимости }}
|текст11 = {{#if: {{{Спорный статус|}}} || {{#if: {{{Дата независимости|}}}{{{Даты независимости|}}} | {{{Дата независимости|{{{Даты независимости|}}}}}} {{#if: {{{Независимость от|}}} | (от {{{Независимость от}}}) }} }} }}
<!-- / СПОРНЫЙ СТАТУС -->
|метка12 = {{#if: {{{Язык|}}} | Официальный язык | Официальные языки }}
|текст12 = {{{Язык|{{{Языки|}}}}}}
|метка13 = Столица
|текст13 = {{{Столица|}}}
|метка14 = {{#if: {{{Крупнейший город|}}} | Крупнейший город | Крупнейшие города }}
|текст14 = {{{Крупнейший город|}}}{{{Крупнейшие города|}}}
|метка15 = Форма правления
|текст15 = {{{Форма правления|}}}
|метка16 = Государственный строй
|текст16 = {{{Государственный строй|}}}
|метка17 = {{{Должность руководителя 1|{{{Должности руководителей}}}}}}
|текст17 = {{{Руководитель 1|{{{Руководители|}}}}}}
|метка18 = {{{Должность руководителя 2}}}
|текст18 = {{{Руководитель 2|}}}
|метка19 = {{{Должность руководителя 3}}}
|текст19 = {{{Руководитель 3|}}}
|метка20 = {{{Должность руководителя 4}}}
|текст20 = {{{Руководитель 4|}}}
|метка21 = {{{Должность руководителя 5}}}
|текст21 = {{{Руководитель 5|}}}
|метка22 = Гос. религия
|текст22 = {{{Государственная религия|}}}
|блок23 =
{{Карточка/блок с маркерами
|подзаголовок = Территория
|метка1 = Всего
|текст1 = {{br separated entries
| {{число|{{{Территория|}}}|км²}}{{#if: {{{Место по территории|}}} | ({{{Место по территории}}}-я в мире) }}
| {{число|{{{Территория2|}}}|км²}}
}}
|метка2 = % водной {{abbr|поверхн.|поверхности|0}}
|текст2 = {{#ifeq: {{{Процент воды|}}} | - || {{{Процент воды|}}} }}
}}
|блок24 =
{{Карточка/блок с маркерами
|подзаголовок = Население
|метка1 = Оценка {{#if: {{{Год оценки|}}} | ({{{Год оценки}}}) }}
|текст1 = {{br separated entries
| {{число|{{{Население|}}}|чел.}}{{#if: {{{Место по населению|}}} | ({{{Место по населению}}}-е) }}
| {{число|{{{Население2|}}}|чел.}}
}}
|метка2 = Перепись {{#if: {{{Год переписи|}}} | ({{{Год переписи}}}) }}
|текст2 = {{число|{{{Население по переписи|}}}|чел.}}
|метка3 = Плотность
|текст3 = {{число|{{{Плотность населения|}}}|чел./км²}}{{#if: {{{Место по плотности|}}} | ({{{Место по плотности}}}-я) }}
}}
|блок25 =
{{Карточка/блок с маркерами
|подзаголовок = ВВП
|метка1 = Итого {{#if: {{{Год расчёта ВВП|}}} | ({{{Год расчёта ВВП}}}) }}
|текст1 = {{число|{{{ВВП|}}}|долл.}}{{#if: {{{Место по ВВП|}}} | ({{{Место по ВВП}}}-й) }}
|метка2 = На душу населения
|текст2 = {{число|{{{ВВП на душу населения|}}}|долл.}}{{#if: {{{Место по ВВП на душу населения|}}} | ({{{Место по ВВП на душу населения}}}-й) }}
}}
|блок26 =
{{Карточка/блок с маркерами
|подзаголовок = ВВП <span style="font-weight:normal;">(ППС)</span>
|метка1 = Итого {{#if: {{{Год расчёта ВВП (ППС)|}}} | ({{{Год расчёта ВВП (ППС)}}}) }}
|текст1 = {{число|{{{ВВП (ППС)|}}}|долл.}}{{#if: {{{Место по ВВП (ППС)|}}} | ({{{Место по ВВП (ППС)}}}-й) }}
|метка2 = На душу населения
|текст2 = {{число|{{{ВВП (ППС) на душу населения|}}}|долл.}}{{#if: {{{Место по ВВП (ППС) на душу населения|}}} | ({{{Место по ВВП (ППС) на душу населения}}}-й) }}
}}
|блок27 =
{{Карточка/блок с маркерами
|подзаголовок = ВВП <span style="font-weight:normal;">(номинал)</span>
|метка1 = Итого {{#if: {{{Год расчёта ВВП (номинал)|}}} | ({{{Год расчёта ВВП (номинал)}}}) }}
|текст1 = {{число|{{{ВВП (номинал)|}}}|долл.}}{{#if: {{{Место по ВВП (номинал)|}}} | ({{{Место по ВВП (номинал)}}}-й) }}
|метка2 = На душу населения
|текст2 = {{число|{{{ВВП (номинал) на душу населения|}}}|долл.}}{{#if: {{{Место по ВВП (номинал) на душу населения|}}} | ({{{Место по ВВП (номинал) на душу населения}}}-й) }}
}}
|метка28 = |ИЧР {{#if: {{{Год расчёта ИРЧП|}}} | <span style="font-weight:normal;">({{{Год расчёта ИРЧП}}})</span> }}
|текст28 = {{{ИРЧП|}}}{{#if: {{{Уровень ИРЧП|}}} | ({{{Уровень ИРЧП}}}{{#if: {{{Место по ИРЧП|}}} | ; {{{Место по ИРЧП}}}-е }}) }}
|метка29 = Названия жителей
|текст29 = {{{Этнохороним|}}}
|метка30 = Валюта
|текст30 = {{{Валюта|}}}
|метка31 = {{#if: {{{Домен|}}}|Интернет-домен}}{{#if: {{{Домены|}}}|Интернет-домены}}
|текст31 = {{{Домен|}}}{{{Домены|}}}
|метка32 = Код ISO
|текст32 =
|метка33 = Код МОК
|текст33 =
|метка34 = Телефонный код
|текст34 = {{#if: {{{Телефонный код|}}} | {{#ifeq: {{{Телефонный код|}}} | - | - | +{{{Телефонный код}}} }} }}
|метка35 = {{#if: {{{Часовой пояс|}}}|Часовой пояс}}{{#if: {{{Часовые пояса|}}}|Часовые пояса}}
|текст35 = {{{Часовой пояс|}}}{{{Часовые пояса|}}}
|метка36 = Автомобильное движение
|текст36 = {{{Автомобильное движение|}}}
|текст37 = {{{Примечания|}}}
|стиль_текста37 = border-top:1px solid #a2a9b1; color:#54595d; padding-top:0.5em; text-align:left;
}}{{#if: {{{nocat|}}}{{NAMESPACE}} || <!--
-->{{#switch: {{{Статус|}}}
| виртуальное = [[Категория:Виртуальные государства]]
| непризнанное = [[Категория:Непризнанные государства]]
| частично признанное = [[Категория:Частично признанные государства]]
| [[Категория:Государства по алфавиту]]
}}
}}<noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude>
d1607f9db45488e75728f7b75e602bb85f314a0d
Шаблон:Abbr
10
232
518
517
2024-08-16T15:58:45Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{#switch: {{{3|1}}}
| 0 = <abbr title="{{#tag:nowiki|{{replace|{{{2}}}|"|"}}}}">{{{1}}}</abbr>
| 1 = [[{{{1}}}|<abbr title="{{#tag:nowiki|{{replace|{{{2}}}|"|"}}}}">{{{1}}}</abbr>]]
| 2 = [[{{{2}}}|<abbr title="{{#tag:nowiki|{{replace|{{{2}}}|"|"}}}}">{{{1}}}</abbr>]]
| #default = [[{{{3}}}|<abbr title="{{#tag:nowiki|{{replace|{{{2}}}|"|"}}}}">{{{1}}}</abbr>]]
}}</includeonly><noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude>
adac845cdff938e70ffb8d2c92101be40d204e3b
Шаблон:Clear
10
188
520
421
2024-08-16T15:58:45Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<div style="clear:{{{1|both}}};"></div><noinclude>{{doc}}</noinclude>
15e943687be5d8f8e27fa6cc7813bbfa85df72a9
Шаблон:Doc
10
171
522
385
2024-08-16T15:58:46Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{doc/begin|{{SUBJECTSPACE}}:{{PAGENAME:{{{1|{{SUBJECTPAGENAME}}/doc}}}}}}}
{{#if: {{{1|}}}
| {{#ifexist: {{{1}}}
| {{{{{1}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}|{{{5|}}}}}
| {{#ifexist: {{SUBJECTSPACE}}:{{{1}}}
| {{{{{1}}}|{{{2|}}}|{{{3|}}}|{{{4|}}}|{{{5|}}}}}
| {{Документировать|{{{1}}}}}
}}
}}
| {{#ifexist: {{SUBJECTPAGENAME}}/doc
| {{{{SUBJECTPAGENAME}}/doc}}
| {{Документировать|{{SUBJECTPAGENAME}}/doc}}
}}
}}
{{doc/end}}</includeonly><noinclude>
{{doc}}
</noinclude>
391c7f0f075319e6b3305557c55e98c581696c71
Шаблон:Doc/begin
10
172
524
387
2024-08-16T15:58:46Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly><templatestyles src="Шаблон:Doc/styles.css" />
<div class="ts-doc-doc" id="doc">
<div class="ts-doc-header" id="Документация">
<div class="ts-doc-heading">Документация</div>
{{#if: {{{inline|}}} || {{Действия для страницы|lc={{{1}}}|nowatch=yes}} }}
</div>
<div class="ts-doc-content"></includeonly><noinclude>
{{doc}}
</noinclude>
c753f0a9f65d86707cdffaf93fb49c2c52daf92b
Шаблон:Doc/end
10
176
526
395
2024-08-16T15:58:47Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly></div>
</div><templatestyles src="Шаблон:Doc/styles.css" />{{#ifexpr: {{NAMESPACENUMBER}} mod 2 = 1 <!-- Например, [[Обсуждение MediaWiki:Robots.txt]] -->
| {{^|1em}}
| <div class="ts-doc-footer plainlinks">
{{#ifeq: {{str left|{{PAGENAME}}|9}}
| Песочница
|
| {{#ifeq: {{str rightc|{{PAGENAME}}|10}}
| /песочница
|
| Во избежание поломок страниц, использующих этот {{#ifeq: {{NAMESPACE}}
| Модуль
| модуль
| шаблон
}}, экспериментируйте в [[Википедия:Правка и тестирование шаблонов в песочнице|песочнице]] <small style="font-style:normal;">({{#ifexist: {{FULLPAGENAME}}/песочница
| [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit}} редактировать] {{!}} [{{fullurl:Special:ComparePages|page1={{FULLPAGENAMEE}}&page2={{FULLPAGENAMEE}}/песочница}} разница] {{#ifexist: {{FULLPAGENAME}}/тесты | {{!}} [[{{FULLPAGENAME}}/тесты|тесты]] }}
| {{#ifeq: {{NAMESPACE}} | Модуль | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit}} создать] | [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit&preload=Шаблон:Doc/предзагрузка-песочница}} создать] {{!}} [{{fullurl:{{FULLPAGENAME}}/песочница|action=edit&preload=Шаблон:Doc/зеркало}} зеркало] }}
}})</small> или {{#ifeq: {{NAMESPACE}}
| Модуль
| [[Модуль:Песочница|песочнице для модулей]]
| своём [[ВП:ЛП|личном пространстве]]
}}.<br>
}}
}}{{#ifexist: {{FULLPAGENAME}}/doc | Пожалуйста, добавляйте категории на подстраницу [[/doc]]. }}[[Special:PrefixIndex/{{FULLPAGENAME}}/|Подстраницы этого {{#ifeq: {{NAMESPACE}}
| Модуль
| модуля
| шаблона
}}]].
</div>
}}</includeonly><noinclude>{{doc}}</noinclude>
758a01a3d76e14ef14b2b0ee047ac47ddac8fd8e
Шаблон:Doc/styles.css
10
173
528
389
2024-08-16T15:58:47Z
DuOfOrl
5
1 версия импортирована
sanitized-css
text/css
.ts-doc-doc {
background-color: var(--background-color-progressive-subtle, #eaf3ff);
border: 1px solid var(--border-color-content-added, #afb6e9);
clear: both;
margin-top: 1em;
}
/* Ctrl+F ":target" in [[MediaWiki:Common.css]] */
.ts-doc-doc sup.reference:target,
.ts-doc-doc ol.references li:target,
.ts-doc-doc .highlight-target:target,
.ts-doc-doc cite:target,
.ts-doc-doc span.citation:target {
background: var(--ruwiki-background-color-blue200, #cfe3ff);
}
.ts-doc-header {
align-items: center;
background: var(--ruwiki-background-color-blue200, #cfe3ff);
display: flex;
flex-wrap: wrap;
padding: .642857em 1em .5em;
overflow: hidden;
}
.ts-doc-header .ts-tlinks-tlinks {
margin-left: auto;
}
.ts-doc-content {
padding: .214286em 1em;
}
.ts-doc-content:after {
content: '';
clear: both;
display: block;
}
.ts-doc-heading {
display: inline-block;
padding-left: 2em;
background: url(//upload.wikimedia.org/wikipedia/commons/c/ca/OOjs_UI_icon_info.svg) center left no-repeat;
background-size: contain;
font-size: small;
min-height: 1.75em;
font-weight: 600;
letter-spacing: 0.1em;
text-transform: uppercase;
}
@media screen {
html.skin-theme-clientpref-night .ts-doc-heading {
background-image: url(//upload.wikimedia.org/wikipedia/commons/c/c0/OOjs_UI_icon_info-invert.svg);
}
}
@media screen and (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os .ts-doc-heading {
background-image: url(//upload.wikimedia.org/wikipedia/commons/c/c0/OOjs_UI_icon_info-invert.svg);
}
}
.ts-doc-content > *:first-child,
.ts-doc-footer > *:first-child {
margin-top: .5em;
}
.ts-doc-content > *:last-child,
.ts-doc-footer > *:last-child {
margin-bottom: .5em;
}
.ts-doc-footer {
background-color: var(--background-color-progressive-subtle, #eaf3ff);
border: 1px solid var(--border-color-content-added, #afb6e9);
padding: .214286em 1em;
margin-top: .214286em;
margin-bottom: .214286em;
font-style: italic;
}
@media (max-width: 719px) {
.ts-doc-header {
display: block;
}
.ts-doc-header .ts-tlinks-tlinks {
float: none;
}
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
be8d912472a37a6051bee114da86f913839e7ca0
605
528
2024-08-16T16:03:37Z
DuOfOrl
5
sanitized-css
text/css
.ts-doc-doc {
background-color: #eaf3ff;
border: 1px solid #a3caff;
margin-top: 1em;
}
.ts-doc-header {
background-color: #c2dcff;
padding: .642857em 1em .5em;
overflow: hidden;
}
.ts-doc-header .ts-tlinks-tlinks {
line-height: 24px;
}
.ts-doc-header .ts-tlinks-tlinks a.external {
color: #0645ad;
}
.ts-doc-header .ts-tlinks-tlinks a.external:visited {
color: #0b0080;
}
.ts-doc-header .ts-tlinks-tlinks a.external:active {
color: #faa700;
}
.ts-doc-content {
padding: .214286em 1em;
}
.ts-doc-content:after {
content: '';
clear: both;
display: block;
}
.ts-doc-heading {
display: inline-block;
padding-left: 30px;
background: url(//upload.wikimedia.org/wikipedia/commons/c/ca/OOjs_UI_icon_info.svg) center left/24px 24px no-repeat;
height: 24px;
line-height: 24px;
font-size: 13px;
font-weight: 600;
letter-spacing: 1px;
text-transform: uppercase;
}
.ts-doc-content > *:first-child,
.ts-doc-footer > *:first-child {
margin-top: .5em;
}
.ts-doc-content > *:last-child,
.ts-doc-footer > *:last-child {
margin-bottom: .5em;
}
.ts-doc-footer {
background-color: #eaf3ff;
border: 1px solid #a3caff;
padding: .214286em 1em;
margin-top: .214286em;
margin-bottom: .214286em;
font-style: italic;
}
@media (max-width: 719px) {
.ts-doc-header .ts-tlinks-tlinks {
float: none;
}
}
/* Данный шаблон использует материал из страницы [[w:ru:Шаблон:Doc/styles.css]] с русскоязычной Википедии, который выпущен под лицензией Creative Commons Attribution-ShareAlike 3.0 Unported.
[[Категория:Шаблоны:Подстраницы CSS]] */
569be9051ed08a2fc9715c629fb275f499513915
Шаблон:Docpage
10
178
530
399
2024-08-16T15:58:47Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{#ifeq: {{SUBPAGENAME}} | doc
| {{fmbox
| class = hlist nowraplinks
| style = margin-bottom:1em; background:var(--background-color-progressive-subtle, #eaf3ff); color:inherit; border:1px solid var(--border-color-content-added, #a3d3ff);
| image = [[Файл:OOjs UI icon info.svg|24px|link=|alt=|class=skin-invert-image]]
| text = <div>
* [[:{{#titleparts: {{SUBJECTPAGENAME}} | -1 }}]]
* [[:{{SUBJECTPAGENAME}}|Документация]]
* [[{{#titleparts: {{TALKPAGENAME}} | -1 }}|Обсуждение]]
* [[Служебная:Whatlinkshere/{{#titleparts: {{SUBJECTPAGENAME}} | -1 }}|Где используется]] {{#ifeq: {{NAMESPACE}} | {{ns:Template}} |
** {{Параметры шаблона|{{#titleparts: {{PAGENAME}} | -1 }}}}
}}</div><!--
-->{{#if: {{{nocat|}}} || {{#ifexist: {{NAMESPACE}}:{{BASEPAGENAME}} || [[Категория:Шаблоны:Документация несуществующих шаблонов]] }} }}
}}{{#if: {{{nocat|}}} || {{#ifeq: {{NAMESPACE}}
| Модуль
| [[Категория:Модули:Документация]]
| [[Категория:Шаблоны:Документация]]
}}
}}
}}</includeonly><noinclude>{{doc}}</noinclude>
9b09d5b771c19e45bd038d248dcf31e500e436ce
Шаблон:Join
10
150
532
343
2024-08-16T15:58:47Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>#invoke:Separated entries|main|separator={{{separator|}}}}}<noinclude>
{{doc}}
<!-- Категории — на подстраницу /doc, интервики — в Викиданные. -->
</noinclude>
92bb17b5322d3ae0ceab93d4dad3d31810d47eb0
Шаблон:Namespace detect
10
233
534
533
2024-08-16T15:58:48Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{#switch:
{{lc: <!--Lower case the result-->
<!--If no or empty "demospace" parameter then detect namespace-->
{{#if:{{{demospace|}}}
| {{{demospace}}}
| {{#ifeq:{{NAMESPACE}}|{{ns:0}}
| main
| {{#ifeq:{{NAMESPACE}}|{{TALKSPACE}}
| {{#if:{{{talk|}}} | talk | {{#if:{{{andtalk|}}}|{{SUBJECTSPACE}}|talk}} }}
| {{NAMESPACE}}
}}
}}
}}
}}
<!-- Only one of the lines below will be executed -->
<!-- Respecting empty parameters on purpose -->
| main = {{{main| {{{other|}}} }}}
| talk
| обсуждение = {{{talk| {{{other|}}} }}}
| user
| участник = {{{user| {{{other|}}} }}}
| wikipedia
| википедия = {{{wikipedia| {{{other|}}} }}}
| file
| image
| файл = {{{file| {{{image| {{{other|}}} }}} }}}
| mediawiki
| медиавики = {{{mediawiki| {{{other|}}} }}}
| template
| шаблон = {{{template| {{{other|}}} }}}
| help
| справка = {{{help| {{{other|}}} }}}
| category
| категория = {{{category| {{{other|}}} }}}
| portal
| портал = {{{portal| {{{other|}}} }}}
| other
| #default = {{{other|}}} <!--"demospace=other" or a new namespace-->
}}<!--End switch--><noinclude>
{{documentation}}{{Указание авторства русскоязычной Википедии}}
</noinclude>
058c2deda5bf3cd3190672c4b14ab9f0c072ce03
Шаблон:Replace
10
145
536
333
2024-08-16T15:58:48Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{safesubst:<noinclude />#invoke:String|replace|source={{{1}}}|{{{2}}}|{{{3}}}|plain={{{plain|true}}}|count={{{count|}}}}}<noinclude>
{{doc}}
</noinclude>
7752c3c70ae8c46a89a0808aa282956866dbba5b
Шаблон:Str left
10
146
538
335
2024-08-16T15:58:49Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>padleft:|{{{2|1}}}|{{{1|}}}}}<noinclude>
{{doc}}
</noinclude>
c1f57b63826f4d455dcaec8d2c24a2b8268f42ec
Шаблон:Str len
10
166
540
375
2024-08-16T15:58:49Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{{{{|safesubst:}}}#invoke:String|len|s={{{1|}}}}}<noinclude>
{{doc}}
<!-- Add categories and interwikis to the /doc subpage, not here! -->
</noinclude>
95f10258d5214440d2706952656564f216c2e4cc
Шаблон:Str rightc
10
167
542
377
2024-08-16T15:58:49Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>Str sub|{{{1}}}|{{<includeonly>safesubst:</includeonly>#expr:{{<includeonly>safesubst:</includeonly>Str len|{{{1}}}}}-{{{2}}}}}|{{{2}}}}}<noinclude>{{doc}}</noinclude>
0401d500dcc2224d44867ba0ea1f6c0fbeb758a0
Шаблон:Str sub
10
164
544
371
2024-08-16T15:58:49Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{{{{|safesubst:}}}#invoke:String|sublength|s={{{1}}}|i={{{2|0}}}|len={{{3|0}}}}}</includeonly><noinclude>
{{doc}}
</noinclude>
3043790f8803e868cf6097b475fd58ba742887fe
Шаблон:T
10
161
546
365
2024-08-16T15:58:50Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
#перенаправление [[Шаблон:Tl]]
c0a76efe437d8a513d9f6878297f399a23944abd
Шаблон:Tl
10
162
548
367
2024-08-16T15:58:50Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{{{{|safesubst:}}}#invoke: Template call code | withoutParams }}<noinclude>{{doc}}</noinclude>
61fe4d068895a5e7e5802767f5d7df71a7561c57
Шаблон:Tlinks
10
234
550
549
2024-08-16T15:58:50Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
#перенаправление [[Шаблон:Действия для страницы]]
8d69cbc167e009846a8f6ad7cd75b790882aeff5
Шаблон:Yesno
10
131
552
305
2024-08-16T15:58:51Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>#switch: {{<includeonly>safesubst:</includeonly>lc: {{{1|¬}}} }}
|no
|n
|нет
|false
|0 = {{{no|<!-- null -->}}}
| = {{{blank|{{{no|<!-- null -->}}}}}}
|¬ = {{{¬|}}}
|yes
|y
|да
|true
|1 = {{{yes|yes}}}
|#default = {{{def|{{{yes|yes}}}}}}
}}<noinclude>
{{Documentation}}
</noinclude>
4e236854c477d07a225c2ab6c016c389b133e8d3
Шаблон:Yesno-yes
10
153
554
349
2024-08-16T15:58:51Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{safesubst:<noinclude />yesno|{{{1}}}|yes={{{yes|yes}}}|no={{{no|no}}}|blank={{{blank|yes}}}|¬={{{¬|yes}}}|def={{{def|yes}}}}}<noinclude>
{{doc}}
</noinclude>
3792ff694708f98102e3a6d556abe73bedc29069
Шаблон:Действия для страницы
10
174
556
391
2024-08-16T15:58:51Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<templatestyles src="Шаблон:Действия для страницы/styles.css" /><div style="{{#ifeq: {{yesno-yes|{{{right|}}}}} | yes || float:none; }}" class="ts-tlinks-tlinks mw-editsection-like plainlinks"><span class="mw-editsection-bracket">[</span><!--
-->{{join|separator=<span class="mw-editsection-divider"> &#124; </span>
|1={{#ifexist: {{#rel2abs: {{{lc|}}} }}
| {{#ifeq: {{{dislooklink|{{{noview|}}}}}} | yes || [[{{{lc}}}|просмотр]] }}
}}
|2={{#ifexist: {{#rel2abs: {{{lc|}}} }}
| [[Special:EditPage/{{#rel2abs: {{{lc}}} }}|править]]
}}
|3={{#ifexist: {{#rel2abs: {{{lc|}}} }}
| {{#ifeq: {{{dishistlink|{{{nohistory|}}}}}} | yes || [[Special:PageHistory/{{#rel2abs: {{{lc}}} }}|история]] }}
}}
|4={{#ifexist: {{#rel2abs: {{{lc|}}} }}
|
| [{{fullurl:{{#rel2abs: {{{lc}}} }}|action=edit&redlink=1}} создать]
}}
|5={{#ifeq: {{{diswatchlink|{{{nowatch|}}}}}} | yes || [{{fullurl:{{#rel2abs: {{{lc}}} }}|action=watch}} следить] }}
|6={{#ifeq: {{{disupdlink|{{{noupdate|}}}}}} | yes || {{очистить кэш|обновить|nocat=1}}</span> }}
}}<span class="mw-editsection-bracket">]</span></div><noinclude>
{{doc}}
</noinclude>
9ee2c9eed92e2ecc9377a7b9486ad8bc214a83d4
Шаблон:Действия для страницы/styles.css
10
175
558
393
2024-08-16T15:58:51Z
DuOfOrl
5
1 версия импортирована
sanitized-css
text/css
.ts-tlinks-tlinks {
font-weight: normal;
float: right;
line-height: inherit;
}
.ts-tlinks-tlinks .mw-editsection-divider {
display: inline;
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
a003e896d263c29e66d2246b210e5d73e577ea46
Шаблон:Указание авторства русскоязычной Википедии
10
235
560
559
2024-08-16T15:58:52Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{| style="border: 1px solid #e0e0e0; background-color: #f8f8f8; color:black; margin: 5px auto; width: 60%;"
|-
| style="padding: 3px 10px;" | [[File:Wikipedia-logo-v2.svg|30px|Wikipedia logo]]
| style="font-size: 90%; padding: 3px;" |{{Namespace detect|template=Данный шаблон|other=Данная страница}} использует материал из {{Namespace detect|template=шаблона|other=страницы}} [[w:ru:{{{1|{{FULLPAGENAME}}}}}|{{{1|{{FULLPAGENAME}}}}}]] с русскоязычной Википедии, который выпущен под [[w:ru:Википедия:Текст лицензии Creative Commons Attribution-ShareAlike 3.0 Unported|лицензией Creative Commons Attribution-ShareAlike 3.0 Unported]] ([https://ru.wikipedia.org/w/index.php?title={{urlencode:{{{1|{{FULLPAGENAME}}}}}}}&action=history посмотреть авторов]).
|}
[[Категория:{{Namespace detect|main=Статьи|category=Категории|file=Файлы|template=Шаблоны|other=Страницы}} из русскоязычной Википедии]]</includeonly>
<noinclude>
{{Doc}}
[[Категория:Шаблоны с указанием авторства]]
{{Указание авторства англоязычной Википедии|Template:En-WP attribution notice}}
</noinclude>
f6a3b5534c9f0bd71170f01c372f6d47cc03c302
Шаблон:Якорь
10
236
562
561
2024-08-16T15:58:53Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{#invoke:якорь|main}}<noinclude>
{{doc}}{{Указание авторства русскоязычной Википедии}}
<!-- Добавляйте категории на страницу документацию, не сюда -->
</noinclude>
d3f6a8195150483ee5b8b616a2aae7afbd3a3e0b
Модуль:Arguments
828
124
564
291
2024-08-16T15:58:53Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
-- This module provides easy processing of arguments passed to Scribunto from
-- #invoke. It is intended for use by other Lua modules, and should not be
-- called from #invoke directly.
local libraryUtil = require('libraryUtil')
local checkType = libraryUtil.checkType
local arguments = {}
-- Generate four different tidyVal functions, so that we don't have to check the
-- options every time we call it.
local function tidyValDefault(key, val)
if type(val) == 'string' then
val = val:match('^%s*(.-)%s*$')
if val == '' then
return nil
else
return val
end
else
return val
end
end
local function tidyValTrimOnly(key, val)
if type(val) == 'string' then
return val:match('^%s*(.-)%s*$')
else
return val
end
end
local function tidyValRemoveBlanksOnly(key, val)
if type(val) == 'string' then
if val:find('%S') then
return val
else
return nil
end
else
return val
end
end
local function tidyValNoChange(key, val)
return val
end
local function matchesTitle(given, title)
local tp = type( given )
return (tp == 'string' or tp == 'number') and mw.title.new( given ).prefixedText == title
end
local translate_mt = { __index = function(t, k) return k end }
function arguments.getArgs(frame, options)
checkType('getArgs', 1, frame, 'table', true)
checkType('getArgs', 2, options, 'table', true)
frame = frame or {}
options = options or {}
--[[
-- Set up argument translation.
--]]
options.translate = options.translate or {}
if getmetatable(options.translate) == nil then
setmetatable(options.translate, translate_mt)
end
if options.backtranslate == nil then
options.backtranslate = {}
for k,v in pairs(options.translate) do
options.backtranslate[v] = k
end
end
if options.backtranslate and getmetatable(options.backtranslate) == nil then
setmetatable(options.backtranslate, {
__index = function(t, k)
if options.translate[k] ~= k then
return nil
else
return k
end
end
})
end
--[[
-- Get the argument tables. If we were passed a valid frame object, get the
-- frame arguments (fargs) and the parent frame arguments (pargs), depending
-- on the options set and on the parent frame's availability. If we weren't
-- passed a valid frame object, we are being called from another Lua module
-- or from the debug console, so assume that we were passed a table of args
-- directly, and assign it to a new variable (luaArgs).
--]]
local fargs, pargs, luaArgs
if type(frame.args) == 'table' and type(frame.getParent) == 'function' then
if options.wrappers then
--[[
-- The wrappers option makes Module:Arguments look up arguments in
-- either the frame argument table or the parent argument table, but
-- not both. This means that users can use either the #invoke syntax
-- or a wrapper template without the loss of performance associated
-- with looking arguments up in both the frame and the parent frame.
-- Module:Arguments will look up arguments in the parent frame
-- if it finds the parent frame's title in options.wrapper;
-- otherwise it will look up arguments in the frame object passed
-- to getArgs.
--]]
local parent = frame:getParent()
if not parent then
fargs = frame.args
else
local title = parent:getTitle():gsub('/песочница$', '')
local found = false
if matchesTitle(options.wrappers, title) then
found = true
elseif type(options.wrappers) == 'table' then
for _,v in pairs(options.wrappers) do
if matchesTitle(v, title) then
found = true
break
end
end
end
-- We test for false specifically here so that nil (the default) acts like true.
if found or options.frameOnly == false then
pargs = parent.args
end
if not found or options.parentOnly == false then
fargs = frame.args
end
end
else
-- options.wrapper isn't set, so check the other options.
if not options.parentOnly then
fargs = frame.args
end
if not options.frameOnly then
local parent = frame:getParent()
pargs = parent and parent.args or nil
end
end
if options.parentFirst then
fargs, pargs = pargs, fargs
end
else
luaArgs = frame
end
-- Set the order of precedence of the argument tables. If the variables are
-- nil, nothing will be added to the table, which is how we avoid clashes
-- between the frame/parent args and the Lua args.
local argTables = {fargs}
argTables[#argTables + 1] = pargs
argTables[#argTables + 1] = luaArgs
--[[
-- Generate the tidyVal function. If it has been specified by the user, we
-- use that; if not, we choose one of four functions depending on the
-- options chosen. This is so that we don't have to call the options table
-- every time the function is called.
--]]
local tidyVal = options.valueFunc
if tidyVal then
if type(tidyVal) ~= 'function' then
error(
"bad value assigned to option 'valueFunc'"
.. '(function expected, got '
.. type(tidyVal)
.. ')',
2
)
end
elseif options.trim ~= false then
if options.removeBlanks ~= false then
tidyVal = tidyValDefault
else
tidyVal = tidyValTrimOnly
end
else
if options.removeBlanks ~= false then
tidyVal = tidyValRemoveBlanksOnly
else
tidyVal = tidyValNoChange
end
end
--[[
-- Set up the args, metaArgs and nilArgs tables. args will be the one
-- accessed from functions, and metaArgs will hold the actual arguments. Nil
-- arguments are memoized in nilArgs, and the metatable connects all of them
-- together.
--]]
local args, metaArgs, nilArgs, metatable = {}, {}, {}, {}
setmetatable(args, metatable)
local function mergeArgs(tables)
--[[
-- Accepts multiple tables as input and merges their keys and values
-- into one table. If a value is already present it is not overwritten;
-- tables listed earlier have precedence. We are also memoizing nil
-- values, which can be overwritten if they are 's' (soft).
--]]
for _, t in ipairs(tables) do
for key, val in pairs(t) do
if metaArgs[key] == nil and nilArgs[key] ~= 'h' then
local tidiedVal = tidyVal(key, val)
if tidiedVal == nil then
nilArgs[key] = 's'
else
metaArgs[key] = tidiedVal
end
end
end
end
end
--[[
-- Define metatable behaviour. Arguments are memoized in the metaArgs table,
-- and are only fetched from the argument tables once. Fetching arguments
-- from the argument tables is the most resource-intensive step in this
-- module, so we try and avoid it where possible. For this reason, nil
-- arguments are also memoized, in the nilArgs table. Also, we keep a record
-- in the metatable of when pairs and ipairs have been called, so we do not
-- run pairs and ipairs on the argument tables more than once. We also do
-- not run ipairs on fargs and pargs if pairs has already been run, as all
-- the arguments will already have been copied over.
--]]
metatable.__index = function (t, key)
--[[
-- Fetches an argument when the args table is indexed. First we check
-- to see if the value is memoized, and if not we try and fetch it from
-- the argument tables. When we check memoization, we need to check
-- metaArgs before nilArgs, as both can be non-nil at the same time.
-- If the argument is not present in metaArgs, we also check whether
-- pairs has been run yet. If pairs has already been run, we return nil.
-- This is because all the arguments will have already been copied into
-- metaArgs by the mergeArgs function, meaning that any other arguments
-- must be nil.
--]]
if type(key) == 'string' then
key = options.translate[key]
end
local val = metaArgs[key]
if val ~= nil then
return val
elseif metatable.donePairs or nilArgs[key] then
return nil
end
for _, argTable in ipairs(argTables) do
local argTableVal = tidyVal(key, argTable[key])
if argTableVal ~= nil then
metaArgs[key] = argTableVal
return argTableVal
end
end
nilArgs[key] = 'h'
return nil
end
metatable.__newindex = function (t, key, val)
-- This function is called when a module tries to add a new value to the
-- args table, or tries to change an existing value.
if type(key) == 'string' then
key = options.translate[key]
end
if options.readOnly then
error(
'could not write to argument table key "'
.. tostring(key)
.. '"; the table is read-only',
2
)
elseif options.noOverwrite and args[key] ~= nil then
error(
'could not write to argument table key "'
.. tostring(key)
.. '"; overwriting existing arguments is not permitted',
2
)
elseif val == nil then
--[[
-- If the argument is to be overwritten with nil, we need to erase
-- the value in metaArgs, so that __index, __pairs and __ipairs do
-- not use a previous existing value, if present; and we also need
-- to memoize the nil in nilArgs, so that the value isn't looked
-- up in the argument tables if it is accessed again.
--]]
metaArgs[key] = nil
nilArgs[key] = 'h'
else
metaArgs[key] = val
end
end
local function translatenext(invariant)
local k, v = next(invariant.t, invariant.k)
invariant.k = k
if k == nil then
return nil
elseif type(k) ~= 'string' or not options.backtranslate then
return k, v
else
local backtranslate = options.backtranslate[k]
if backtranslate == nil then
-- Skip this one. This is a tail call, so this won't cause stack overflow
return translatenext(invariant)
else
return backtranslate, v
end
end
end
metatable.__pairs = function ()
-- Called when pairs is run on the args table.
if not metatable.donePairs then
mergeArgs(argTables)
metatable.donePairs = true
end
return translatenext, { t = metaArgs }
end
local function inext(t, i)
-- This uses our __index metamethod
local v = t[i + 1]
if v ~= nil then
return i + 1, v
end
end
metatable.__ipairs = function (t)
-- Called when ipairs is run on the args table.
return inext, t, 0
end
return args
end
return arguments
e6be8dfccffa2057c3d50700f350d8d140c1dbf9
Модуль:Separated entries
828
158
566
359
2024-08-16T15:58:53Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
-- This module takes positional parameters as input and concatenates them with
-- an optional separator. The final separator (the "conjunction") can be
-- specified independently, enabling natural-language lists like
-- "foo, bar, baz and qux".
local compressSparseArray = require('Module:TableTools').compressSparseArray
local p = {}
function p._main(args)
local separator = args.separator
-- Decode (convert to Unicode) HTML escape sequences, such as " " for space.
and mw.text.decode(args.separator) or ''
local conjunction = args.conjunction and mw.text.decode(args.conjunction) or separator
-- Discard named parameters.
local values = compressSparseArray(args)
return mw.text.listToText(values, separator, conjunction)
end
local function makeInvokeFunction(separator, conjunction)
return function (frame)
local args = require('Module:Arguments').getArgs(frame)
args.separator = separator or args.separator
args.conjunction = conjunction or args.conjunction
return p._main(args)
end
end
p.main = makeInvokeFunction()
p.br = makeInvokeFunction('<br />')
p.newline = makeInvokeFunction('\n')
p.comma = makeInvokeFunction(mw.message.new('comma-separator'):plain())
return p
33a68f0a46d62c42b6523a548f0f881e82ecfe58
Модуль:String
828
138
568
319
2024-08-16T15:58:54Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
--[[
This module is intended to provide access to basic string functions.
Most of the functions provided here can be invoked with named parameters,
unnamed parameters, or a mixture. If named parameters are used, Mediawiki will
automatically remove any leading or trailing whitespace from the parameter.
Depending on the intended use, it may be advantageous to either preserve or
remove such whitespace.
Global options
ignore_errors: If set to 'true' or 1, any error condition will result in
an empty string being returned rather than an error message.
error_category: If an error occurs, specifies the name of a category to
include with the error message. The default category is
[Category:Errors reported by Module String].
no_category: If set to 'true' or 1, no category will be added if an error
is generated.
Unit tests for this module are available at Module:String/tests.
]]
local str = {}
--[[
subcount
This function returns the count of substring in source string.
Usage:
{{#invoke:String|subcount|source_string|substring|plain_flag}}
OR
{{#invoke:String|subcount|s=source_string|pattern=substring|plain=plain_flag}}
Parameters
s: The string to search
pattern: The pattern or string to find within the string
plain: A flag indicating that the substring should be understood as plain
text. Defaults to true.
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the target string.
]]
function str.subcount( frame )
local new_args = str._getParameters( frame.args, {'s', 'pattern', 'plain'} );
local s = new_args['s'] or '';
local plain_flag = str._getBoolean( new_args['plain'] or true );
local pattern = new_args['pattern'] or '';
if s == '' or pattern == '' then
return 0;
end
if plain_flag then
pattern = str._escapePattern( pattern );
end
local _, count = mw.ustring.gsub(s, pattern, "")
return count;
end
--[[
len
This function returns the length of the target string.
Usage:
{{#invoke:String|len|target_string|}}
OR
{{#invoke:String|len|s=target_string}}
Parameters
s: The string whose length to report
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the target string.
]]
function str.len( frame )
local new_args = str._getParameters( frame.args, {'s'} );
local s = new_args['s'] or '';
return mw.ustring.len( s )
end
--[[
sub
This function returns a substring of the target string at specified indices.
Usage:
{{#invoke:String|sub|target_string|start_index|end_index}}
OR
{{#invoke:String|sub|s=target_string|i=start_index|j=end_index}}
Parameters
s: The string to return a subset of
i: The fist index of the substring to return, defaults to 1.
j: The last index of the string to return, defaults to the last character.
The first character of the string is assigned an index of 1. If either i or j
is a negative value, it is interpreted the same as selecting a character by
counting from the end of the string. Hence, a value of -1 is the same as
selecting the last character of the string.
If the requested indices are out of range for the given string, an error is
reported.
]]
function str.sub( frame )
local new_args = str._getParameters( frame.args, { 's', 'i', 'j' } );
local s = new_args['s'] or '';
local i = tonumber( new_args['i'] ) or 1;
local j = tonumber( new_args['j'] ) or -1;
local len = mw.ustring.len( s );
-- Convert negatives for range checking
if i < 0 then
i = len + i + 1;
end
if j < 0 then
j = len + j + 1;
end
if i > len or j > len or i < 1 or j < 1 then
return str._error( 'Значение индекса подстроки выходит за допустимые границы' );
end
if j < i then
return str._error( 'Неверный порядок индексов подстроки' );
end
return mw.ustring.sub( s, i, j )
end
--[[
This function implements that features of {{str sub old}} and is kept in order
to maintain these older templates.
]]
function str.sublength( frame )
local i = tonumber( frame.args.i ) or 0
local len = tonumber( frame.args.len )
return mw.ustring.sub( frame.args.s, i + 1, len and ( i + len ) )
end
--[[
match
This function returns a substring from the source string that matches a
specified pattern.
Usage:
{{#invoke:String|match|source_string|pattern_string|start_index|match_number|plain_flag|nomatch_output}}
OR
{{#invoke:String|pos|s=source_string|pattern=pattern_string|start=start_index
|match=match_number|plain=plain_flag|nomatch=nomatch_output}}
Parameters
s: The string to search
pattern: The pattern or string to find within the string
start: The index within the source string to start the search. The first
character of the string has index 1. Defaults to 1.
match: In some cases it may be possible to make multiple matches on a single
string. This specifies which match to return, where the first match is
match= 1. If a negative number is specified then a match is returned
counting from the last match. Hence match = -1 is the same as requesting
the last match. Defaults to 1.
plain: A flag indicating that the pattern should be understood as plain
text. Defaults to false.
nomatch: If no match is found, output the "nomatch" value rather than an error.
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from each string. In some circumstances this is desirable, in
other cases one may want to preserve the whitespace.
If the match_number or start_index are out of range for the string being queried, then
this function generates an error. An error is also generated if no match is found.
If one adds the parameter ignore_errors=true, then the error will be suppressed and
an empty string will be returned on any failure.
For information on constructing Lua patterns, a form of [regular expression], see:
* http://www.lua.org/manual/5.1/manual.html#5.4.1
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Patterns
* http://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual#Ustring_patterns
]]
function str.match( frame )
local new_args = str._getParameters( frame.args, {'s', 'pattern', 'start', 'match', 'plain', 'nomatch'} );
local s = new_args['s'] or '';
local start = tonumber( new_args['start'] ) or 1;
local plain_flag = str._getBoolean( new_args['plain'] or false );
local pattern = new_args['pattern'] or '';
local match_index = math.floor( tonumber(new_args['match']) or 1 );
local nomatch = new_args['nomatch'];
if s == '' then
return str._error( 'Пустая строка поиска' );
end
if pattern == '' then
return str._error( 'Пустой шаблон поиска' );
end
if math.abs(start) < 1 or math.abs(start) > mw.ustring.len( s ) then
return str._error( 'Индекс начала поиска выходит за допустимые границы' );
end
if match_index == 0 then
return str._error( 'Индекс совпадения выходит за допустимые границы' );
end
if plain_flag then
pattern = str._escapePattern( pattern );
end
local result
if match_index == 1 then
-- Find first match is simple case
result = mw.ustring.match( s, pattern, start )
else
if start > 1 then
s = mw.ustring.sub( s, start );
end
local iterator = mw.ustring.gmatch(s, pattern);
if match_index > 0 then
-- Forward search
for w in iterator do
match_index = match_index - 1;
if match_index == 0 then
result = w;
break;
end
end
else
-- Reverse search
local result_table = {};
local count = 1;
for w in iterator do
result_table[count] = w;
count = count + 1;
end
result = result_table[ count + match_index ];
end
end
if result == nil then
if nomatch == nil then
return str._error( 'Совпадение не найдено' );
else
return nomatch;
end
else
return result;
end
end
--[[
pos
This function returns a single character from the target string at position pos.
Usage:
{{#invoke:String|pos|target_string|index_value}}
OR
{{#invoke:String|pos|target=target_string|pos=index_value}}
Parameters
target: The string to search
pos: The index for the character to return
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the target string. In some circumstances this is desirable, in
other cases one may want to preserve the whitespace.
The first character has an index value of 1.
If one requests a negative value, this function will select a character by counting backwards
from the end of the string. In other words pos = -1 is the same as asking for the last character.
A requested value of zero, or a value greater than the length of the string returns an error.
]]
function str.pos( frame )
local new_args = str._getParameters( frame.args, {'target', 'pos'} );
local target_str = new_args['target'] or '';
local pos = tonumber( new_args['pos'] ) or 0;
if pos == 0 or math.abs(pos) > mw.ustring.len( target_str ) then
return str._error( 'Значение индекса строки выходит за допустимые границы' );
end
return mw.ustring.sub( target_str, pos, pos );
end
--[[
str_find
This function duplicates the behavior of {{str_find}}, including all of its quirks.
This is provided in order to support existing templates, but is NOT RECOMMENDED for
new code and templates. New code is recommended to use the "find" function instead.
Returns the first index in "source" that is a match to "target". Indexing is 1-based,
and the function returns -1 if the "target" string is not present in "source".
Important Note: If the "target" string is empty / missing, this function returns a
value of "1", which is generally unexpected behavior, and must be accounted for
separatetly.
]]
function str.str_find( frame )
local new_args = str._getParameters( frame.args, {'source', 'target'} );
local source_str = new_args['source'] or '';
local target_str = new_args['target'] or '';
if target_str == '' then
return 1;
end
local start = mw.ustring.find( source_str, target_str, 1, true )
if start == nil then
start = -1
end
return start
end
--[[
find
This function allows one to search for a target string or pattern within another
string.
Usage:
{{#invoke:String|find|source_str|target_string|start_index|plain_flag}}
OR
{{#invoke:String|find|source=source_str|target=target_str|start=start_index|plain=plain_flag}}
Parameters
source: The string to search
target: The string or pattern to find within source
start: The index within the source string to start the search, defaults to 1
plain: Boolean flag indicating that target should be understood as plain
text and not as a Lua style regular expression, defaults to true
If invoked using named parameters, Mediawiki will automatically remove any leading or
trailing whitespace from the parameter. In some circumstances this is desirable, in
other cases one may want to preserve the whitespace.
This function returns the first index >= "start" where "target" can be found
within "source". Indices are 1-based. If "target" is not found, then this
function returns 0. If either "source" or "target" are missing / empty, this
function also returns 0.
This function should be safe for UTF-8 strings.
]]
function str.find( frame )
local new_args = str._getParameters( frame.args, {'source', 'target', 'start', 'plain' } );
local source_str = new_args['source'] or '';
local pattern = new_args['target'] or '';
local start_pos = tonumber(new_args['start']) or 1;
local plain = new_args['plain'] or true;
if source_str == '' or pattern == '' then
return 0;
end
plain = str._getBoolean( plain );
local start = mw.ustring.find( source_str, pattern, start_pos, plain )
if start == nil then
start = 0
end
return start
end
--[[
replace
This function allows one to replace a target string or pattern within another
string.
Usage:
{{#invoke:String|replace|source_str|pattern_string|replace_string|replacement_count|plain_flag}}
OR
{{#invoke:String|replace|source=source_string|pattern=pattern_string|replace=replace_string|
count=replacement_count|plain=plain_flag}}
Parameters
source: The string to search
pattern: The string or pattern to find within source
replace: The replacement text
count: The number of occurences to replace, defaults to all.
plain: Boolean flag indicating that pattern should be understood as plain
text and not as a Lua style regular expression, defaults to true
]]
function str.replace( frame )
local new_args = str._getParameters( frame.args, {'source', 'pattern', 'replace', 'count', 'plain' } );
local source_str = new_args['source'] or '';
local pattern = new_args['pattern'] or '';
local replace = new_args['replace'] or '';
local count = tonumber( new_args['count'] );
local plain = new_args['plain'] or true;
if source_str == '' or pattern == '' then
return source_str;
end
plain = str._getBoolean( plain );
if plain then
pattern = str._escapePattern( pattern );
replace = mw.ustring.gsub( replace, "%%", "%%%%" ); --Only need to escape replacement sequences.
end
local result;
if count ~= nil then
result = mw.ustring.gsub( source_str, pattern, replace, count );
else
result = mw.ustring.gsub( source_str, pattern, replace );
end
return result;
end
--[[
This function adds support for escaping parts of the patterns when using [plain=false].
]]
function str.escape( frame )
local new_args = str._getParameters( frame.args, {'pattern' } );
local pattern = new_args['pattern'] or '';
local result = '';
result = str._escapePattern( pattern );
return result;
end
--[[
Internal compare string function
]]
function str._strcmp(a , b)
local s1c = mw.ustring.gcodepoint( a );
local s2c = mw.ustring.gcodepoint( b );
while true do
local c1 = s1c();
local c2 = s2c();
if c1 == nil then
if c2 == nil then
return 0
else
return -1
end
else
if c2 ~= nil then
if c1 ~= c2 then
return c1 < c2 and -1 or 1
end
else
return 1
end
end
end
return 0
end
--[[
compare
This function compare two UTF-8 strings
Usage:
{{#invoke:String|compare|str1|str2}}
Returns:
0 - if strings are equal
1 - if st1 > str2
-1 - if str1 < str2
]]
function str.compare(frame)
local str1 = frame.args[1] or '';
local str2 = frame.args[2] or '';
return str._strcmp(str1 , str2)
end
--[[
simple function to pipe string.rep to templates.
]]
function str.rep( frame )
local repetitions = tonumber( frame.args[2] )
if not repetitions then
return str._error( 'функция rep ожидает число во втором параметре, а получено "' .. ( frame.args[2] or '' ) .. '"' )
end
return string.rep( frame.args[1] or '', repetitions )
end
--[[
Helper function that populates the argument list given that user may need to use a mix of
named and unnamed parameters. This is relevant because named parameters are not
identical to unnamed parameters due to string trimming, and when dealing with strings
we sometimes want to either preserve or remove that whitespace depending on the application.
]]
function str._getParameters( frame_args, arg_list )
local new_args = {};
local index = 1;
local value;
for i,arg in ipairs( arg_list ) do
value = frame_args[arg]
if value == nil then
value = frame_args[index];
index = index + 1;
end
new_args[arg] = value;
end
return new_args;
end
--[[
Helper function to handle error messages.
]]
function str._error( error_str )
local frame = mw.getCurrentFrame();
local error_category = frame.args.error_category or 'Страницы с ошибками модуля String';
local ignore_errors = frame.args.ignore_errors or false;
local no_category = frame.args.no_category or false;
if str._getBoolean(ignore_errors) then
return '';
end
local error_str = '<strong class="error">Ошибка модуля String: ' .. error_str .. '</strong>';
if error_category ~= '' and not str._getBoolean( no_category ) then
error_str = '[[Категория:' .. error_category .. ']]' .. error_str;
end
return error_str;
end
--[[
Helper Function to interpret boolean strings
]]
function str._getBoolean( boolean_str )
local boolean_value;
if type( boolean_str ) == 'string' then
boolean_str = boolean_str:lower();
if boolean_str == 'false' or boolean_str == 'no' or boolean_str == '0'
or boolean_str == '' then
boolean_value = false;
else
boolean_value = true;
end
elseif type( boolean_str ) == 'boolean' then
boolean_value = boolean_str;
else
error( 'Логическое значение не найдено' );
end
return boolean_value
end
--[[
Helper function that escapes all pattern characters so that they will be treated
as plain text.
]]
function str._escapePattern( pattern_str )
return mw.ustring.gsub( pattern_str, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" );
end
return str
b4a4e099d7fab23576bae7af327a44c87d13f9cb
Модуль:TableTools
828
125
570
293
2024-08-16T15:58:54Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
--[[
------------------------------------------------------------------------------------
-- TableTools --
-- --
-- This module includes a number of functions for dealing with Lua tables. --
-- It is a meta-module, meant to be called from other Lua modules, and should --
-- not be called directly from #invoke. --
------------------------------------------------------------------------------------
--]]
local libraryUtil = require('libraryUtil')
local p = {}
-- Define often-used variables and functions.
local floor = math.floor
local infinity = math.huge
local checkType = libraryUtil.checkType
local checkTypeMulti = libraryUtil.checkTypeMulti
--[[
------------------------------------------------------------------------------------
-- isPositiveInteger
--
-- This function returns true if the given value is a positive integer, and false
-- if not. Although it doesn't operate on tables, it is included here as it is
-- useful for determining whether a given table key is in the array part or the
-- hash part of a table.
------------------------------------------------------------------------------------
--]]
function p.isPositiveInteger(v)
if type(v) == 'number' and v >= 1 and floor(v) == v and v < infinity then
return true
else
return false
end
end
--[[
------------------------------------------------------------------------------------
-- isNan
--
-- This function returns true if the given number is a NaN value, and false
-- if not. Although it doesn't operate on tables, it is included here as it is
-- useful for determining whether a value can be a valid table key. Lua will
-- generate an error if a NaN is used as a table key.
------------------------------------------------------------------------------------
--]]
function p.isNan(v)
if type(v) == 'number' and tostring(v) == '-nan' then
return true
else
return false
end
end
--[[
------------------------------------------------------------------------------------
-- shallowClone
--
-- This returns a clone of a table. The value returned is a new table, but all
-- subtables and functions are shared. Metamethods are respected, but the returned
-- table will have no metatable of its own.
------------------------------------------------------------------------------------
--]]
function p.shallowClone(t)
local ret = {}
for k, v in pairs(t) do
ret[k] = v
end
return ret
end
--[[
------------------------------------------------------------------------------------
-- removeDuplicates
--
-- This removes duplicate values from an array. Non-positive-integer keys are
-- ignored. The earliest value is kept, and all subsequent duplicate values are
-- removed, but otherwise the array order is unchanged.
------------------------------------------------------------------------------------
--]]
function p.removeDuplicates(t)
checkType('removeDuplicates', 1, t, 'table')
local isNan = p.isNan
local ret, exists = {}, {}
for i, v in ipairs(t) do
if isNan(v) then
-- NaNs can't be table keys, and they are also unique, so we don't need to check existence.
ret[#ret + 1] = v
else
if not exists[v] then
ret[#ret + 1] = v
exists[v] = true
end
end
end
return ret
end
--[[
------------------------------------------------------------------------------------
-- numKeys
--
-- This takes a table and returns an array containing the numbers of any numerical
-- keys that have non-nil values, sorted in numerical order.
------------------------------------------------------------------------------------
--]]
function p.numKeys(t)
checkType('numKeys', 1, t, 'table')
local isPositiveInteger = p.isPositiveInteger
local nums = {}
for k, v in pairs(t) do
if isPositiveInteger(k) then
nums[#nums + 1] = k
end
end
table.sort(nums)
return nums
end
--[[
------------------------------------------------------------------------------------
-- affixNums
--
-- This takes a table and returns an array containing the numbers of keys with the
-- specified prefix and suffix. For example, for the table
-- {a1 = 'foo', a3 = 'bar', a6 = 'baz'} and the prefix "a", affixNums will
-- return {1, 3, 6}.
------------------------------------------------------------------------------------
--]]
function p.affixNums(t, prefix, suffix)
checkType('affixNums', 1, t, 'table')
checkType('affixNums', 2, prefix, 'string', true)
checkType('affixNums', 3, suffix, 'string', true)
local function cleanPattern(s)
-- Cleans a pattern so that the magic characters ()%.[]*+-?^$ are interpreted literally.
s = s:gsub('([%(%)%%%.%[%]%*%+%-%?%^%$])', '%%%1')
return s
end
prefix = prefix or ''
suffix = suffix or ''
prefix = cleanPattern(prefix)
suffix = cleanPattern(suffix)
local pattern = '^' .. prefix .. '([1-9]%d*)' .. suffix .. '$'
local nums = {}
for k, v in pairs(t) do
if type(k) == 'string' then
local num = mw.ustring.match(k, pattern)
if num then
nums[#nums + 1] = tonumber(num)
end
end
end
table.sort(nums)
return nums
end
--[[
------------------------------------------------------------------------------------
-- numData
--
-- Given a table with keys like ("foo1", "bar1", "foo2", "baz2"), returns a table
-- of subtables in the format
-- { [1] = {foo = 'text', bar = 'text'}, [2] = {foo = 'text', baz = 'text'} }
-- Keys that don't end with an integer are stored in a subtable named "other".
-- The compress option compresses the table so that it can be iterated over with
-- ipairs.
------------------------------------------------------------------------------------
--]]
function p.numData(t, compress)
checkType('numData', 1, t, 'table')
checkType('numData', 2, compress, 'boolean', true)
local ret = {}
for k, v in pairs(t) do
local prefix, num = mw.ustring.match(tostring(k), '^([^0-9]*)([1-9][0-9]*)$')
if num then
num = tonumber(num)
local subtable = ret[num] or {}
if prefix == '' then
-- Positional parameters match the blank string; put them at the start of the subtable instead.
prefix = 1
end
subtable[prefix] = v
ret[num] = subtable
else
local subtable = ret.other or {}
subtable[k] = v
ret.other = subtable
end
end
if compress then
local other = ret.other
ret = p.compressSparseArray(ret)
ret.other = other
end
return ret
end
--[[
------------------------------------------------------------------------------------
-- compressSparseArray
--
-- This takes an array with one or more nil values, and removes the nil values
-- while preserving the order, so that the array can be safely traversed with
-- ipairs.
------------------------------------------------------------------------------------
--]]
function p.compressSparseArray(t)
checkType('compressSparseArray', 1, t, 'table')
local ret = {}
local nums = p.numKeys(t)
for _, num in ipairs(nums) do
ret[#ret + 1] = t[num]
end
return ret
end
--[[
------------------------------------------------------------------------------------
-- sparseIpairs
--
-- This is an iterator for sparse arrays. It can be used like ipairs, but can
-- handle nil values.
------------------------------------------------------------------------------------
--]]
function p.sparseIpairs(t)
checkType('sparseIpairs', 1, t, 'table')
local nums = p.numKeys(t)
local i = 0
local lim = #nums
return function ()
i = i + 1
if i <= lim then
local key = nums[i]
return key, t[key]
else
return nil, nil
end
end
end
--[[
------------------------------------------------------------------------------------
-- size
--
-- This returns the size of a key/value pair table. It will also work on arrays,
-- but for arrays it is more efficient to use the # operator.
------------------------------------------------------------------------------------
--]]
function p.size(t)
checkType('size', 1, t, 'table')
local i = 0
for k in pairs(t) do
i = i + 1
end
return i
end
local function defaultKeySort(item1, item2)
-- "number" < "string", so numbers will be sorted before strings.
local type1, type2 = type(item1), type(item2)
if type1 ~= type2 then
return type1 < type2
else -- This will fail with table, boolean, function.
return item1 < item2
end
end
--[[
Returns a list of the keys in a table, sorted using either a default
comparison function or a custom keySort function.
]]
function p.keysToList(t, keySort, checked)
if not checked then
checkType('keysToList', 1, t, 'table')
checkTypeMulti('keysToList', 2, keySort, { 'function', 'boolean', 'nil' })
end
local list = {}
local index = 1
for key, value in pairs(t) do
list[index] = key
index = index + 1
end
if keySort ~= false then
keySort = type(keySort) == 'function' and keySort or defaultKeySort
table.sort(list, keySort)
end
return list
end
--[[
Iterates through a table, with the keys sorted using the keysToList function.
If there are only numerical keys, sparseIpairs is probably more efficient.
]]
function p.sortedPairs(t, keySort)
checkType('sortedPairs', 1, t, 'table')
checkType('sortedPairs', 2, keySort, 'function', true)
local list = p.keysToList(t, keySort, true)
local i = 0
return function()
i = i + 1
local key = list[i]
if key ~= nil then
return key, t[key]
else
return nil, nil
end
end
end
--[[
Returns true if all keys in the table are consecutive integers starting at 1.
--]]
function p.isArray(t)
checkType("isArray", 1, t, "table")
local i = 0
for k, v in pairs(t) do
i = i + 1
if t[i] == nil then
return false
end
end
return true
end
-- { "a", "b", "c" } -> { a = 1, b = 2, c = 3 }
function p.invert(array)
checkType("invert", 1, array, "table")
local map = {}
for i, v in ipairs(array) do
map[v] = i
end
return map
end
--[[
{ "a", "b", "c" } -> { ["a"] = true, ["b"] = true, ["c"] = true }
--]]
function p.listToSet(t)
checkType("listToSet", 1, t, "table")
local set = {}
for _, item in ipairs(t) do
set[item] = true
end
return set
end
--[[
Recursive deep copy function.
Preserves identities of subtables.
]]
local function _deepCopy(orig, includeMetatable, already_seen)
-- Stores copies of tables indexed by the original table.
already_seen = already_seen or {}
local copy = already_seen[orig]
if copy ~= nil then
return copy
end
if type(orig) == 'table' then
copy = {}
for orig_key, orig_value in pairs(orig) do
copy[deepcopy(orig_key, includeMetatable, already_seen)] = deepcopy(orig_value, includeMetatable, already_seen)
end
already_seen[orig] = copy
if includeMetatable then
local mt = getmetatable(orig)
if mt ~= nil then
local mt_copy = deepcopy(mt, includeMetatable, already_seen)
setmetatable(copy, mt_copy)
already_seen[mt] = mt_copy
end
end
else -- number, string, boolean, etc
copy = orig
end
return copy
end
function p.deepCopy(orig, noMetatable, already_seen)
checkType("deepCopy", 3, already_seen, "table", true)
return _deepCopy(orig, not noMetatable, already_seen)
end
--[[
Concatenates all values in the table that are indexed by a number, in order.
sparseConcat{ a, nil, c, d } => "acd"
sparseConcat{ nil, b, c, d } => "bcd"
]]
function p.sparseConcat(t, sep, i, j)
local list = {}
local list_i = 0
for _, v in p.sparseIpairs(t) do
list_i = list_i + 1
list[list_i] = v
end
return table.concat(list, sep, i, j)
end
--[[
-- This returns the length of a table, or the first integer key n counting from
-- 1 such that t[n + 1] is nil. It is similar to the operator #, but may return
-- a different value when there are gaps in the array portion of the table.
-- Intended to be used on data loaded with mw.loadData. For other tables, use #.
-- Note: #frame.args in frame object always be set to 0, regardless of
-- the number of unnamed template parameters, so use this function for
-- frame.args.
--]]
function p.length(t)
local i = 1
while t[i] ~= nil do
i = i + 1
end
return i - 1
end
function p.inArray(arr, valueToFind)
checkType("inArray", 1, arr, "table")
-- if valueToFind is nil, error?
for _, v in ipairs(arr) do
if v == valueToFind then
return true
end
end
return false
end
return p
fe918509f168332267834b3a6f5c219a9de5b2e7
Модуль:Template call code
828
126
572
295
2024-08-16T15:58:55Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
local getArgs = require('Module:Arguments').getArgs
local ru = mw.language.new('ru')
local p = {}
-- Используется для того, чтобы можно было удалять элементы из таблицы
local function copy(other)
local res = {}
for k, v in pairs(other) do
res[k] = v
end
return res
end
local function makeInvokeFunc(funcName, flags)
return function (frame)
local args = copy(getArgs(frame, {
trim = false,
removeBlanks = false
}))
return p[funcName](args, flags)
end
end
--предотвращает обработку вики-текста в отображении образца
local function processText(str, nowiki)
local res = str
if nowiki then
str = mw.text.unstripNoWiki(str)
str = string.gsub(str, '%[', '[')
str = string.gsub(str, '%]', ']')
str = string.gsub(str, '<', '<')
str = string.gsub(str, '>', '>')
str = string.gsub(str, '{', '{')
str = string.gsub(str, '|', '|')
str = string.gsub(str, '}', '}')
str = string.gsub(str, '\'', ''')
str = string.gsub(str, '"', '"')
str = string.gsub(str, '(://)', '<span>%1</span>')
end
return str
end
local function addParams(args, params)
local text, equals_pos, param, value = '', 0, '', ''
local function addPipe()
if params.spaced then
text = text .. ' '
end
text = text .. '<span class="'
if not params.spaced then
text = text .. ' ts-templateCallCode-pipe'
end
if not params.black then
text = text .. ' ts-templateCallCode-weak'
end
-- |, чтобы не трактовалось как разделитель ячеек в таблицах
text = text .. '">|</span>'
end
local beforeParam = '<span class="ts-templateCallCode-param">'
local afterParam = '</span>'
for k, v in pairs(args) do
if type(k) == 'number' then -- Неименованные параметры
if k >= params.from then
equals_pos = v:find('=')
if equals_pos and v:find('{{=}}') == equals_pos - 2 then
equals_pos = nil
end
if equals_pos then -- Содержащие «=» преобразуем в именованные
param = v:sub(1, equals_pos - 1)
value = v:sub(equals_pos + 1)
addPipe()
text = text .. beforeParam .. processText(param, params.nowiki) .. '=' .. processText(value, params.nowiki) .. afterParam
else -- Истинно неименованные
addPipe()
local paramValue = processText(v, params.nowiki)
if #paramValue ~= 0 then
text = text .. beforeParam .. paramValue .. afterParam
end
end
end
elseif not k:find('^_') then -- Именованные параметры, исключая модификаторы внешнего вида
addPipe()
text = text .. beforeParam .. processText(k, params.nowiki) .. '=' .. processText(v, params.nowiki) .. afterParam
end
end
return text
end
function p._main(args, flags)
local name = args[1]
table.remove(args, 1)
-- Вещи типа «=» в первом параметре
if not name then
for k, v in pairs(args) do
if not k:find('^_') then
name = k .. '=' .. v
args[k] = nil
break
end
end
end
local optpText
if not flags.withoutParams then
if name then
local spanOffset = mw.ustring.find(name, '<span') -- След использования шаблона optp
if spanOffset then
optpText = mw.ustring.sub(name, spanOffset)
name = mw.ustring.sub(name, 1, spanOffset - 1)
end
end
end
local yesno = require('Module:Yesno')
local nolink, subst, podst, global, nav, noRedirect, ucFirst, black, nobr
local tag, style, comment, lang, sister, global, textInPlaceOfName,
namePrefix, prefix, postfix, nowiki
local spaced, from
if flags.withoutParams then
for i, v in ipairs(args) do
if v == 'nl' or v == 'nolink' then
noLink = true
elseif v == 's' then
subst = true
elseif v == 'п' then
podst = true
elseif v == 'g' then
global = true
elseif v == 'nav' then
nav = true
elseif v == 'noredir' then
noRedirect = true
elseif v == 'u' then
ucFirst = true
elseif v == 'b' then
black = true
elseif v == 'nobr' then
nobr = true
end
end
tag = args.tag or 'span'
style = args.style
comment = args.comment
lang = args.lang
sister = args.sister
textInPlaceOfName = args.text
namePrefix = args.nameprefix
prefix = args.prefix
postfix = args.postfix
nowiki = args.nowiki
else
noLink = yesno(args._nolink or args._nl, false) or not yesno(args._link, false)
subst = yesno(args._s, false)
podst = yesno(args['_п'], false)
global = yesno(args._g, false)
nav = yesno(args._nav, false)
noRedirect = yesno(args._noredir, false)
ucFirst = yesno(args._u, false)
black = yesno(args._b, false)
nobr = yesno(args._nobr, false)
tag = args._tag or 'span'
style = args._style
comment = args._comment
lang = args._lang
sister = args._sister
textInPlaceOfName = args._text
namePrefix = args._nameprefix
prefix = args._prefix
postfix = args._postfix
nowiki = args._nowiki
spaced = yesno(args._spaced, false)
from = (tonumber(args._from) or 2) - 1
end
global = global or name and mw.ustring.sub(name, 1, 1) == ':'
black = black or tag ~= 'span'
if textInPlaceOfName == '' then
textInPlaceOfName = nil
end
if comment == '' then
comment = nil
end
if lang == '' then
lang = nil
end
if sister == '' then
sister = nil
end
if namePrefix == '' then
namePrefix = nil
end
if name then
local trimmedName = mw.text.trim(name)
if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'subst:' then
subst = true
name = mw.ustring.sub(trimmedName, 7)
end
if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'подст:' then
podst = true
name = mw.ustring.sub(trimmedName, 7)
end
end
if subst then
namePrefix = 'subst:'
elseif podst then
namePrefix = 'подст:'
end
local currentTitle = mw.title.getCurrentTitle()
-- При опущенном первом параметре берём имя шаблона из названия страницы
if name == '' or not name then
local currentTitleRoot = currentTitle.rootText
if not ucFirst and
(
(
ru:uc(currentTitleRoot) ~= currentTitleRoot and
-- Книга:Литературное наследство, TranslateDate
not mw.ustring.match(currentTitleRoot, '^[А-Яа-яA-Za-z]+:?[А-ЯA-Z]')
) or
#currentTitleRoot == 1
)
then
name = ru:lcfirst(currentTitleRoot)
else
name = currentTitleRoot
end
end
-- Начинаем собирать код
local linkBody, titleObject, linkBegin, linkDivider, linkEnd
local prefixes = {}
if lang then
table.insert(prefixes, lang)
end
if sister then
table.insert(prefixes, sister)
end
linkBody = table.concat(prefixes, ':')
if #linkBody ~= 0 then
linkBody = ':' .. linkBody
end
if mw.ustring.sub(name, 1, 1) ~= ':' then
linkBody = linkBody .. ':'
end
if not global then
linkBody = linkBody .. 'Template:'
end
linkBody = linkBody .. name
titleObject = mw.title.new(linkBody)
local noLink = noLink or currentTitle == titleObject
if not noLink then
if not noRedirect or (
noRedirect and
not lang and
not sister and
not titleObject.exists
) then
linkBegin = '[['
linkEnd = ']]'
linkDivider = '|'
else
linkBegin = '['
linkEnd = ']'
linkDivider = ' '
linkBody = titleObject:fullUrl('redirect=no')
end
end
local text = ''
if tag then
text = text .. '<' .. tag .. ' class="ts-templateCallCode'
if nobr then
text = text .. ' nowrap'
end
text = text .. '"'
if style then
text = text .. ' style="' .. style .. '"'
end
text = text .. '>'
end
if prefix then
text = text .. processText(prefix, nowiki)
end
text = text .. '<span class="'
if not spaced then
text = text .. ' ts-templateCallCode-opening'
end
if not black then
text = text .. ' ts-templateCallCode-weak'
end
text = text .. '">{{'
if namePrefix then
text = text .. namePrefix
end
text = text .. '</span>'
if nav and currentTitle == titleObject then
text = text .. '\'\'\''
end
text = text .. '<span class="ts-templateCallCode-templateName" data-navboxnavigation-link="0">'
local commentedLabel
if comment then
-- https://phabricator.wikimedia.org/T200704
-- commentedLabel = mw.getCurrentFrame():expandTemplate({title = 'comment', args = {(textInPlaceOfName or name), comment}})
commentedLabel = '<span class="commentedText" title="' .. comment .. '" style="border-bottom: 1px dotted; cursor: help;">' ..
(textInPlaceOfName or name) ..
'</span>'
end
local label = (commentedLabel or textInPlaceOfName or name)
if not noLink then
if noRedirect then
text = text .. '<span class="plainlinks">'
end
text = text .. linkBegin .. linkBody .. linkDivider .. label .. linkEnd
if noRedirect then
text = text .. '</span>'
end
else
text = text .. label
end
text = text .. '</span>'
if nav and currentTitle == titleObject then
text = text .. '\'\'\''
end
if not flags.withoutParams then
if optpText then
text = text .. optpText
end
text = text .. addParams(args, {
spaced = spaced,
black = black,
nowiki = nowiki,
from = from
})
if spaced then
text = text .. ' '
end
end
text = text .. '<span class="'
if not spaced then
text = text .. ' ts-templateCallCode-closing'
end
if not black then
text = text .. ' ts-templateCallCode-weak'
end
text = text .. '">}}</span>'
if postfix then
text = text .. processText(postfix, nowiki)
end
if tag then
text = text .. '</' .. tag .. '>'
end
local ts = mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = { src = 'Модуль:Template call code/styles.css' } }
return ts .. text
end
function p._onlyParams(args)
local yesno = require('Module:Yesno')
return addParams(args, {
spaced = yesno(args._spaced, false),
black = true,
nowiki = yesno(args._nowiki, false),
from = 1
})
end
p.withoutParams = makeInvokeFunc('_main', {withoutParams = true})
p.withParams = makeInvokeFunc('_main', {withoutParams = false})
p.onlyParams = makeInvokeFunc('_onlyParams')
return p
c4cde66869b509219e9bf629a766ce30ad0bdf97
Модуль:Yesno
828
127
574
297
2024-08-16T15:58:55Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
-- Function allowing for consistent treatment of boolean-like wikitext input.
-- It works similarly to the template {{yesno}}.
return function (val, default)
-- If your wiki uses non-ascii characters for any of "yes", "no", etc., you
-- should replace "val:lower()" with "mw.ustring.lower(val)" in the
-- following line.
val = type(val) == 'string' and val:lower() or val
if val == nil then
return nil
elseif val == true
or val == 'yes'
or val == 'y'
or val == 'true'
or val == 't'
or val == 'да'
or val == 'д'
-- кириллица
or val == 'у'
or val == '+'
or tonumber(val) == 1
then
return true
elseif val == false
or val == 'no'
or val == 'n'
or val == 'false'
or val == 'f'
or val == 'нет'
or val == 'н'
or val == '-'
or tonumber(val) == 0
then
return false
else
return default
end
end
ae94e12a838e770797317ed07b57b330ffeb7658
Модуль:Якорь
828
237
576
575
2024-08-16T15:58:55Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')
local compressSparseArray = require('Module:TableTools').compressSparseArray
local p = {}
local function add_anchor(anchor, text, visible)
local result = mw.html.create('span')
:attr('id', anchor)
:wikitext(text)
if visible then
result:addClass('highlight-target')
end
return tostring(result)
end
local function unpack(...)
local frame = ...
local args
if type(frame.args) == 'table' then
args = getArgs(frame)
elseif type(frame) == 'table' then
args = frame
else
args = {...}
end
return args
end
function p.main(...)
local args = unpack(...)
local anchors = compressSparseArray(args)
local text
local visible = yesno(args.visible or args.v)
if visible then
text = args.text or args['текст'] or args[1]
end
local result = text
for i, v in ipairs(anchors) do
result = add_anchor(anchors[i], result, visible)
--[[
создание старого вида якорей для совместимости,
см. Обсуждение шаблона:Якорь#Новые html5 ссылки и старые
]]
local encoded_anchor = mw.uri.encode(anchors[i], 'WIKI'):gsub('%%', '.')
if anchors[i] ~= encoded_anchor then
result = add_anchor(encoded_anchor, result, visible)
end
end
return result
end
return p
2cd9bcc85d4af30c1681bbadfc7d10c60a63e5f2
Шаблон:Ifsubst
10
238
578
577
2024-08-16T15:58:57Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{ {{{|safesubst:}}}#ifeq:{{ {{{|safesubst:}}}NAMESPACE}}|{{NAMESPACE}}
|{{{no|{{{2|}}}}}}
|{{{yes|{{{1|}}}}}}
}}<noinclude>
{{Documentation}}
</noinclude>
4f51452ff12b7e72ad15c39cba7e3cc7a76b39d4
Шаблон:Optp
10
239
580
579
2024-08-16T15:58:57Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{{{{|safesubst:}}}#invoke: Template call code | onlyParams }}<noinclude>{{doc}}</noinclude>
3e116ca0e893f9ea7b938dae72067678b03bc173
Шаблон:Optp/color
10
240
582
581
2024-08-16T15:58:58Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{{{{|safesubst:}}}ifsubst|1=<!--
--><code style="color: {{optp/color}};">{{{1}}}</code>|2=<!--
--><nowiki>#</nowiki>888888<!--
-->}}<noinclude>
[[Категория:Шаблоны:Подстраницы шаблонов]]
[[Категория:Шаблоны:Цвет]]
[[Категория:Шаблоны:Используемые с подстановкой]]
</noinclude>
571a67174168634a24211fe1d5fcaa4727e150f1
Шаблон:Пример
10
241
584
583
2024-08-16T15:58:58Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{#invoke:Example|main}}</includeonly><noinclude>{{doc}}</noinclude>
6c4efd62aa820f26f326813cddd4cfd909b9bd7a
Модуль:Example
828
242
586
585
2024-08-16T15:58:59Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
local p = {}
-- используется для того, чтобы можно было удалять элементы из таблицы
local function copy(other)
local res = {}
for k,v in pairs(other) do
res[k] = v
end
return res
end
-- вызов шаблона, при ошибке возвращает пустую строку
local function expand(frame, tname, targs)
local success, result = pcall(
frame.expandTemplate,
frame,
{title = tname, args = targs}
)
if success then
return result
else
return ''
end
--return frame:expandTemplate({title = tname, args = args})
end
--предотвращает обработку вики-текста в отображении образца
local function nowiki(str)
local res = str
str = mw.text.unstripNoWiki(str)
str = string.gsub(str, '%[', '[')
str = string.gsub(str, '%]', ']')
str = string.gsub(str, '<', '<')
str = string.gsub(str, '>', '>')
str = string.gsub(str, '{', '{')
str = string.gsub(str, '|', '|')
str = string.gsub(str, '}', '}')
str = string.gsub(str, '\'', ''')
str = string.gsub(str, '"', '"')
str = string.gsub(str, '(://)', '<span>%1</span>')
return str
end
--удаляет из параметров вписанные через HTML-сущности "<nowiki>" и заменяет "{{=}}" на "=" для вызова шаблона
local function process_nowiki_equals(str)
str = str:gsub('<nowiki>', ''):gsub('</nowiki>', '')
:gsub('<nowiki>', ''):gsub('</nowiki>', '')
:gsub('{{=}}', '=')
:gsub('{{=}}', '=')
:gsub('{{=}}', '=')
:gsub('{{=}}', '=')
:gsub('&', '&')
return str
end
function p.main(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
local yesno = require('Module:Yesno')
local args = copy(getArgs(frame, {trim = false, removeBlanks = false})) --copy(frame.args)
local tag = args._tag
local container = args._container or nil
local ucFirst = yesno(args._u, false)
local link = yesno(args._link, false)
local sep = args._sep and args._sep .. ' '
local endl = args._endl or ''
local prefix = args._prefix or args['_pre-text'] or ''
local postfix = args._postfix or args['_post-text'] or ''
local nobr = yesno(args._nobr, false)
local spaced = yesno(args._spaced, false)
local nocat = yesno(args._nocat, false)
local style = args._style
if style == '' then
style = nil
end
-- передаётся шаблоном {{стопка примеров}}, один разделитель на все примеры
local comment_sep = args._comment_sep
-- полезно в шаблоне {{стопка примеров}} (это просто текст в конце)
local after = args._after or args._comment
-- полезно в шаблоне {{стопка примеров}} (это просто текст в начале)
local before = args._before and args._before .. ' ' or ''
if style == 'pre' then
if not (tag or container) then
container = 'pre'
end
sep = sep or '\n'
elseif style == '*pre' then
if not (tag or container) then
container = '*pre'
end
sep = sep or '\n'
elseif style == 'pre↓' then
if not (tag or container) then
container = 'pre'
end
-- содержимое шаблона {{sp↓|50%||-0.5em}}
sep = sep or '<div style="margin:-0.5em 50% 0.7em;"><span style="font-size:150%;">↓</span></div>\n'
elseif style == '*pre↓' then
if not (tag or container) then
container = '*pre'
end
-- содержимое шаблона {{sp↓|50%||-0.5em}}
sep = sep or '<div style="margin:-0.5em 50% 0.7em;"><span style="font-size:150%;">↓</span></div>\n'
elseif style == 'wikitable' then
if not (tag or container) then
tag = 'kbd'
end
sep = sep or '\n| '
comment_sep = '\n| '
end
if not (tag or container) then
tag = 'code'
end
if not sep then
sep = '→ '
end
if not comment_sep then
comment_sep = ' '
end
if (after) then
if not style then
after = '<small>' .. after .. '</small>'
end
after = comment_sep .. after
end
if not after then
after = ''
end
local nwt
if tag then
nwt = mw.html.create(tag):tag(tag) -- "no-wiki tag", внутри него шаблон не вызывается
if nobr then
nwt:css('white-space', 'nowrap')
end
end
local content = nowiki(prefix) .. '{{' -- для накопления содержимого тэга
local tname = args._template or args[1]
if tname == nil then -- если имя шаблона содержит знак "=" (работает, только если нет неименованных параметров)
local nextfunc, static, cur = pairs(args)
local k, v = nextfunc(static, cur)
if k ~= nil and type(k) ~= 'number' and not k:find('^_') then -- именованные параметры, исключая модификаторы внешнего вида
tname = k .. "=" .. v
args[k] = nil --больше этот параметр нам не пригодится
end
end
if tname == '' or tname == nil then -- при опущенном первом параметре берём имя шаблона из названия страницы
local ru = mw.language.new('ru')
local currentTitle = mw.title.getCurrentTitle().rootText
if not ucFirst and
((ru:uc(currentTitle) ~= currentTitle and -- названия со всеми заглавными буквами
not mw.ustring.match(currentTitle, '^[А-Яа-яA-Za-z]+:?[А-ЯA-Z]') -- Книга:Литературное наследство, TranslateDate
) or
#currentTitle == 1
)
then
tname = ru:lcfirst(currentTitle)
else
tname = currentTitle
end
end
-- Имя вызываемого шаблона в неименованном первом параметре (или же взято из названия страницы или
-- из именованного параметра в отсутствие неименованных — в следующей строчке вреда нет в любом случае),
-- больше его обрабатывать не надо
if args._template == nil then
table.remove(args,1)
end
if link then
content = content .. '[[Шаблон:' .. tname .. '|' .. tname .. ']]'
else
content = content .. tname
end
content = content .. endl
local targs, equals_pos, param, value, left_shift = {}, 0, '', '', 0
for k, v in pairs(args) do
if type(k) == 'number' then -- неименованные параметры
equals_pos = v:find('=')
if equals_pos and v:find('{{=}}') == equals_pos-2 then
equals_pos = nil
end
if equals_pos then -- содержащие "=" преобразуем в именованные
param = v:sub(1, equals_pos-1)
value = v:sub(equals_pos+1)
targs[param] = process_nowiki_equals(value)
content = content .. (spaced and ' ' or '') .. '|' .. nowiki(param) .. '=' .. nowiki(value) .. endl
left_shift = left_shift + 1 -- переменная нужна, чтобы квазинумерованные параметры, переданные через "{{=}}",
-- не сбивали порядок
else -- истинно неименованные
targs[k - left_shift] = process_nowiki_equals(v)
content = content .. (spaced and ' ' or '') .. '|' .. nowiki(v) .. endl
end
elseif not k:find('^_') then -- именованные параметры, исключая модификаторы внешнего вида
targs[k] = process_nowiki_equals(v)
content = content .. (spaced and ' ' or '') .. '|' .. nowiki(k) .. '=' .. nowiki(v) .. endl
end
end
if spaced then
content = content .. ' '
end
content = content .. '}}' .. nowiki(postfix)
if container then
local container_args = {}
container_args[1] = content
nwt = expand(frame, container, container_args)
else
nwt:wikitext(content):done()
end
if nocat then
targs['nocat'] = 1
end
expand_result = tostring(expand(frame, tname, targs))
if expand_result:sub(1, 2) == '{|' then
sep = sep .. '\n'
end
return before .. tostring(nwt) .. ' ' .. sep .. prefix .. expand_result .. postfix .. after
end
return p
bbcc2db5eb699c86d081437122681304ac0c12b8
Шаблон:Str find
10
214
588
477
2024-08-16T15:58:59Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{ {{{|safesubst:}}}#invoke:String|str_find|source={{{1|}}}|{{{2|}}}}}<noinclude>
{{doc}}
<!-- Add categories and interwikis to the /doc subpage, not here! -->
</noinclude>
18d1469d30d27a82ee15fd2fb1ca12a34b5f5e87
Шаблон:=
10
243
590
589
2024-08-16T15:59:00Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
=<noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude>
014d0de3d5673019255be0e21b88cdb2037871db
Шаблон:Tc
10
244
592
591
2024-08-16T15:59:01Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{{{{|safesubst:}}}#invoke: Template call code | withParams | _tag = {{{_tag|code}}} }}<noinclude>{{doc}}</noinclude>
db6f042f5bfd10e28e4554066fa696babcc884b2
Шаблон:Optp/comment
10
245
594
593
2024-08-16T15:59:01Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<p style="font-size:85%;">Серым {{#ifeq: {{{1|}}} | 1 | показан необязательный параметр | показаны необязательные параметры }}.</p><noinclude>
{{doc-inline}}
* {{пример|optp/comment}}
* {{пример|optp/comment|1}}
{{doc-end}}
[[Категория:Шаблоны:Подстраницы шаблонов]]
</noinclude>
57a6d9eaf58c69ac5e07d5a55c4de17d34d427bf
Шаблон:^
10
246
596
595
2024-08-16T15:59:01Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<div style=margin-top:{{#if:{{{1|}}}|{{{1}}}|2em}}></div><noinclude>{{doc}}<!-- Пожалуйста, добавляйте категории и интервики на страницу документации! --></noinclude>
8a2941bfb74cc487b19b1ce656a0d7b49cfb9a8e
Шаблон:Другие названия шаблона
10
247
598
597
2024-08-16T15:59:02Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly>[[w:ru:ВП:Перенаправления|{{#if:{{{2|}}}|Другие названия|Другое название}}]] этого шаблона{{#if:{{{2|}}}|:| —}} <!--
-->{{#if:{{{1|}}}|{{t|{{{1}}}|noredir}} |<strong class=error>Не указано ни одного альтернативного названия!</strong>}}<!--
-->{{#if:{{{2|}}}|, {{t|{{{2}}}|noredir}} }}<!--
-->{{#if:{{{3|}}}|, {{t|{{{3}}}|noredir}} }}<!--
-->{{#if:{{{4|}}}|, {{t|{{{4}}}|noredir}} }}<!--
-->{{#if:{{{5|}}}|, {{t|{{{5}}}|noredir}} }}<!--
-->{{#if:{{{6|}}}|, {{t|{{{6}}}|noredir}} }}<!--
-->{{#if:{{{7|}}}|, {{t|{{{7}}}|noredir}} }}<!--
-->{{#if:{{{8|}}}|, {{t|{{{8}}}|noredir}} }}<!--
-->{{#if:{{{9|}}}| [{{fullurl:Служебная:Ссылки сюда/{{FULLPAGENAMEE}}|hidelinks=1&hidetrans=1}} и др.]|{{#if:{{{comment|}}}| ({{{comment}}})}}}}.</includeonly><noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude>
7b543dddf959926ff3a8b3d1ae7894515a88b0a0
Шаблон:Abbr/doc
10
248
600
599
2024-08-16T15:59:03Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{docpage}}
Этот шаблон выделяет [[w:ru:Аббревиатура|аббревиатуру]] подчёркиванием и добавляет к ней всплывающую подсказку с расшифровкой. Он во многом похож на шаблон {{tl|comment}}.
Шаблон может установить ссылку на статью, имя которой — значение 1-го, 2-го или 3-го параметра, например: {{abbr|РФ|Российская Федерация|w:ru:Россия}}.
{{днш|аббревиатура|аббр}}
== Использование ==
{{tc||''аббревиатура''|''расшифровка''{{optp|''№ параметра для ссылки или 0, чтобы подавить ссылку''}}}}
{{optp/comment}}{{^|1em}}
Необязательный третий параметр указывает, какой из параметров использовать для ссылки в качестве названия статьи.
* <code>0</code> — подавить ссылку
* <code>1</code> (по умолчанию) — использовать 1-й параметр (<code>''аббревиатура''</code>)
* <code>2</code> — использовать 2-й параметр (<code>''расшифровка''</code>)
* другое — использовать 3-й (этот же) параметр
== Примеры ==
* Ссылка подавлена:
: {{пример||ПТЗ|Павлодарский тракторный завод|0}}
* Ссылка по умолчанию или явно использует содержимое 1-го параметра:
: {{tc||w:ru:АН СССР|Академия наук СССР}}<br><span style="margin-left: 6px;">или</span><br>{{пример||w:ru:АН СССР|Академия наук СССР|1|_sep={{sp↓|||0}}}} <!-- интервики на википедию чтоб не требовало страниц -->
* Ссылка использует содержимое 2-го параметра:
: {{пример||ПАВ|w:ru:поверхностно-активные вещества|2}}
* Ссылка на произвольную страницу в 3-м параметре:
: {{пример||ПАВ|поверхностно-активные вещества|w:ru:Психоактивные вещества}}
: В данном случае ПАВ расшифровано как «поверхностно-активные вещества», ссылка указывает на статью «[[w:ru:Психоактивные вещества|Психоактивные вещества]]».
== Технические ограничения ==
Технические ограничения те же, что и в шаблоне {{tl|comment}}.
* Если в параметрах шаблона есть знак <code>=</code>, то, как и в любом другом шаблоне, приходится использовать явные номера параметров: {{tc|comment|1{{=}}текст|2{{=}}подсказка}}.
* В некоторых браузерах длина всплывающей подсказки ограничена. Например, в браузере Mozilla Firefox до третьей версии подсказки были однострочными.
* Пользователи [[w:ru:смартфон|смартфонов]] и [[w:ru:Планшетный компьютер|планшетных компьютеров]], как правило, не имеют возможности увидеть всплывающую подсказку, поэтому используйте данный шаблон только там, где это действительно необходимо.
<includeonly>
[[Категория:Шаблоны:Форматирование]]
[[Категория:Шаблоны:Внутренние ссылки]]
</includeonly>
060aec5d84b5320d02f9c95e1cd0427e110f1315
Шаблон:Sp↓
10
249
602
601
2024-08-16T15:59:04Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<div style="margin-left:{{#if: {{{1|}}} | {{{1}}} | 1.3em }}; {{#if: {{{2|}}} | margin-top:{{{2}}}; }} margin-bottom:{{#if: {{{3|}}} | {{{3}}} | 0.7em }};"><span style="font-size:{{#if: {{{size|}}} | {{{size}}} | {{#ifeq: {{str find|{{{1|}}}|%}} | -1 | 120% | 150% }} }};">↓</span></div><noinclude>{{doc}}</noinclude>
e0d0479cdd64d3e90be2c1c2d1b3c3502312f926
Шаблон:Днш
10
250
604
603
2024-08-16T15:59:04Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
#REDIRECT [[Шаблон:Другие названия шаблона]]
310154c4badc00ae3faf727456b5aba85e337ba6
Шаблон:Карточка
10
129
606
502
2024-08-16T16:10:59Z
DuOfOrl
5
wikitext
text/x-wiki
<table class="infobox {{{класс_тела|}}}" style="{{{стиль_тела|}}}" {{#if:{{{имя|}}}|{{#ifeq:{{{имя|}}}|-||data-name="{{{имя}}}"}}}}><!--
Вверху0
-->{{#if:{{{вверху0|}}}|<tr><td colspan="2" class="{{{класс_вверху0|}}}" style="text-align:center; {{{стиль_вверху0|}}}">{{{вверху0}}}</td></tr>}}<!--
Вверху
-->{{#if:{{{вверху|}}}|<tr><th colspan="2" class="infobox-above {{{класс_вверху|}}}" style="{{{стиль_вверху|}}}">{{{вверху}}}</th></tr>}}<!--
Вверху2
-->{{#if:{{{вверху2|}}}|<tr><td colspan="2" class="{{{класс_вверху2|}}}" style="text-align:center; {{{стиль_вверху2|}}}">{{{вверху2}}}</td></tr>}}<!--
Вверху3
-->{{#if:{{{вверху3|}}}|<tr><td colspan="2" class="{{{класс_вверху3|}}}" style="text-align:center; {{{стиль_вверху3|}}}">{{{вверху3}}}</td></tr>}}<!--
Изображение
-->{{#if:{{{изображение|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения|}}}" style="{{{стиль_изображения|}}}"> {{{изображение}}} {{#if:{{{подпись|}}}|
<div class="media-caption" style="{{{стиль_подписи|}}}">{{{подпись}}}</div>}}</td></tr>}}<!--
Изображение2
-->{{#if:{{{изображение2|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения2|}}}" style="{{{стиль_изображения2|}}}"> {{{изображение2}}} {{#if:{{{подпись2|}}}|
<div class="media-caption" style="{{{стиль_подписи2|}}}">{{{подпись2}}}</div>}}</td></tr>}}<!--
Изображение3
-->{{#if:{{{изображение3|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения3|}}}" style="{{{стиль_изображения3|}}}"> {{{изображение3}}} {{#if:{{{подпись3|}}}|
<div class="media-caption" style="{{{стиль_подписи3|}}}">{{{подпись3}}}</div>}}</td></tr>}}<!--
Строки
-->{{#invoke:Infobox|renderLines}}<!--
Внизу
-->{{Карточка/внизу|
стиль_внизу_общий={{{стиль_внизу|}}}|
класс_внизу={{{класс_внизу|}}}|
внизу={{{внизу|}}}}}<!--
Внизу N
-->{{#invoke:Transclude|npc|Карточка/внизу|
стиль_внизу_общий={{{стиль_внизу|}}}|
стиль_внизу=|
класс_внизу=|
внизу=}}
</table><includeonly><!--
статьи
-->{{#if:{{NAMESPACE}}||<!--
-->{{#if:{{{имя|}}}||[[Категория:Статьи с шаблонами-карточками без имени]]}}<!--
-->{{#ifeq:{{{имя|}}}|{{subst:PAGENAME}}|[[Категория:Статьи с шаблонами-карточками без имени]]}}<!--
-->}}<!--
шаблоны
-->{{#ifeq:{{NAMESPACENUMBER}}|10|<!--
-->{{#if:{{{имя|}}}||[[Категория:Шаблоны-карточки без имени]]}}<!--
-->{{#ifeq:{{{имя|}}}|{{subst:PAGENAME}}|[[Категория:Шаблоны-карточки без имени]]}}<!--
-->{{#if:{{{название|}}}{{{стиль_названия|}}}|[[Категория:Шаблоны с использованием параметра «название» в шаблоне «Карточка»]]}}<!--
-->{{#if:{{{подпись|}}}{{{стиль_подписи|}}}{{{подпись2|}}}{{{стиль_подписи2|}}}{{{подпись3|}}}{{{стиль_подписи3|}}}|[[Категория:Шаблоны с использованием параметра «подпись» в шаблоне «Карточка»]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_тела|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_названия|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху2|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху3|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи2|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи3|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_заголовков|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_меток|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_текста|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_внизу|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifeq:{{{имя|}}}|{{PAGENAME}}| [[Категория:Шаблоны-карточки по алфавиту|{{ucfirst:{{без начала|{{PAGENAME}}|Карточка }}}}]]}}<!--
-->}}<!--
любое пространство имён
-->{{#if:{{{название|}}}{{{стиль_названия|}}}|[[Категория:Страницы с использованием параметра «название» в шаблоне «Карточка»]]}}<!--
-->{{#if:{{{подпись|}}}{{{стиль_подписи|}}}{{{подпись2|}}}{{{стиль_подписи2|}}}{{{подпись3|}}}{{{стиль_подписи3|}}}|[[Категория:Страницы с использованием параметра «подпись» в шаблоне «Карточка»]]}}</includeonly><noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude>
8b14ccc682362e6ed5a194621133805aea17ab0d
Модуль:No globals
828
251
608
607
2024-08-16T16:17:36Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
local mt = getmetatable(_G) or {}
function mt.__index (t, k)
if k ~= 'arg' then
error('Tried to read nil global ' .. tostring(k), 2)
end
return nil
end
function mt.__newindex(t, k, v)
if k ~= 'arg' then
error('Tried to write global ' .. tostring(k), 2)
end
rawset(t, k, v)
end
setmetatable(_G, mt)
8ce3969f7d53b08bd00dabe4cc9780bc6afd412a
Шаблон:Ombox
10
20
610
425
2024-08-16T16:22:34Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{#invoke:Message box|ombox}}<noinclude>
{{doc}}<!-- Add categories and interwikis to the /doc subpage, not here! --></noinclude>
ab34435c5ebc29de589c9b059e88da5d0e6f16e4
Модуль:Calendar
828
62
612
97
2024-08-16T16:22:38Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
local p = {}
-- Необходимые модули и переменные
local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')
local mwlang = mw.getContentLanguage()
local err = "―" -- NthDay nil result
local tCon = table.concat
-- 00) Блок многократно используемых списков
local bool_to_number={ [true]=1, [false]=0 }
local monthlang = {"января","февраля","марта","апреля","мая","июня","июля","августа","сентября","октября","ноября","декабря"}
local month_to_num = {["января"]=1,["февраля"]=2,["марта"]=3,["апреля"]=4,["мая"]=5,["июня"]=6,
["июля"]=7,["августа"]=8,["сентября"]=9,["октября"]=10,["ноября"]=11,["декабря"]=12,["-"]=""}
local monthd = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
local params = { {"г", "g"}, {"ю", "j"}}
local comment = { '<span style="border-bottom: 1px dotted; cursor: help" title="по юлианскому календарю">','</span>'}
-- duplicates:
-- AST, BST, CST, ECT, IST, MST, PST, SST,
local known_tzs = {
ACDT='+10:30', ACST='+09:30', ACT ='+08:00', ADT ='-03:00', AEDT ='+11:00',
AEST='+10:00', AFT ='+04:30', AKDT='-08:00', AKST ='-09:00', AMST ='+05:00',
AMT ='+04:00', ART ='-03:00', AST ='+03:00', AST ='+04:00', AST ='+03:00',
AST ='-04:00', AWDT='+09:00', AWST='+08:00', AZOST='-01:00', AZT ='+04:00',
BDT ='+08:00', BIOT='+06:00', BIT ='-12:00', BOT ='-04:00', BRT ='-03:00',
BST ='+06:00', BST ='+01:00', BTT ='+06:00', CAT ='+02:00', CCT ='+06:30',
CDT ='-05:00', CEDT='+02:00', CEST='+02:00', CET ='+01:00', CHAST='+12:45',
CIST='-08:00', CKT ='-10:00', CLST='-03:00', CLT ='-04:00', COST ='-04:00',
COT ='-05:00', CST ='-06:00', CST ='+08:00', CVT ='-01:00', CXT ='+07:00',
CHST='+10:00', DFT ='+01:00', EAST='-06:00', EAT ='+03:00', ECT ='-04:00',
ECT ='-05:00', EDT ='-04:00', EEDT='+03:00', EEST ='+03:00', EET ='+02:00',
EST ='-05:00', FJT ='+12:00', FKST='-03:00', FKT ='-04:00', GALT ='-06:00',
GET ='+04:00', GFT ='-03:00', GILT='+12:00', GIT ='-09:00', GMT ='+00:00',
GST ='-02:00', GYT ='-04:00', HADT='-09:00', HAST ='-10:00', HKT ='+08:00',
HMT ='+05:00', HST ='-10:00', IRKT='+08:00', IRST ='+03:30', IST ='+05:30',
IST ='+01:00', IST ='+02:00', JST ='+09:00', KRAT ='+07:00', KST ='+09:00',
LHST='+10:30', LINT='+14:00', MAGT='+11:00', MDT ='-06:00', MIT ='-09:30',
MSD ='+04:00', MSK ='+03:00', MST ='+08:00', MST ='-07:00', MST ='+06:30',
MUT ='+04:00', NDT ='-02:30', NFT ='+11:30', NPT ='+05:45', NST ='-03:30',
NT ='-03:30', OMST='+06:00', PDT ='-07:00', PETT ='+12:00', PHOT ='+13:00',
PKT ='+05:00', PST ='-08:00', PST ='+08:00', RET ='+04:00', SAMT ='+04:00',
SAST='+02:00', SBT ='+11:00', SCT ='+04:00', SLT ='+05:30', SST ='-11:00',
SST ='+08:00', TAHT='-10:00', THA ='+07:00', UTC ='+00:00', UYST ='-02:00',
UYT ='-03:00', VET ='-04:30', VLAT='+10:00', WAT ='+01:00', WEDT ='+01:00',
WEST='+01:00', WET ='+00:00', YAKT='+09:00', YEKT ='+05:00',
-- US Millitary (for RFC-822)
Z='+00:00', A='-01:00', M='-12:00', N='+01:00', Y='+12:00',
}
local category = {
["no_parameters"]=
"<!--[[Категория:Модуль:Calendar:Страницы без параметров]]-->",
["incomplete_parameters"]=
"<!--[[Категория:Модуль:Calendar:Страницы с неполными или некорректными параметрами]]-->",
["without_verification"]=
"<!--[[Категория:Модуль:Calendar:Страницы без проверки параметров]]-->",
["erroneous_parameters"]=
"<!--[[Категория:Модуль:Calendar:Страницы с ошибочными параметрами]]-->"
}
-- несколько параметров передаются вместе с кодом ошибки в таблице, один может быть передан простым значением
local e = {
["start"]="<span class=error>Ошибка: ",
["ending"]=".</span>",
["no_pattern_match"]="строка «%s» не совпадает с заданными паттернами",
["no_valid_date"]="дата «%s» не является корректной",
["wrong_jd"]="юлианская дата %s вне диапазона",
["no_data"]="нет входящих данных",
["too_many_arguments"]="ожидается менее %i аргументов",
["too_little_arguments"]="ожидается более %i аргументов",
["wrong_calculation"]="даты %s и %s не прошли проверку, %s дней разница",
["unknown_param"]="параметр %s неизвестен",
["unknown_error"]="неизвестная ошибка",
["tech_error"]="ошибка в функции %s",
["box_date"]="строка «%s» не является верной датой, пожалуйста, укажите дату в формате ГГГГ-ММ-ДД"
-- [""]="",
}
local tzs_names = {"ACDT","ACST","ACT","ADT","AEDT","AEST","AFT","AKDT","AKST",
"AMST","AMT","ART","AST","AST","AST","AST","AWDT","AWST","AZOST","AZT","BDT",
"BIOT","BIT","BOT","BRT","BST","BST","BTT","CAT","CCT","CDT","CEDT","CEST",
"CET","CHAST","CIST","CKT","CLST","CLT","COST","COT","CST","CST","CVT","CXT",
"CHST","DFT","EAST","EAT","ECT","ECT","EDT","EEDT","EEST","EET","EST","FJT",
"FKST","FKT","GALT","GET","GFT","GILT","GIT","GMT","GST","GYT","HADT","HAST",
"HKT","HMT","HST","IRKT","IRST","IST","IST","IST","JST","KRAT","KST","LHST",
"LINT","MAGT","MDT","MIT","MSD","MSK","MST","MST","MST","MUT","NDT","NFT",
"NPT","NST","NT","OMST","PDT","PETT","PHOT","PKT","PST","PST","RET","SAMT",
"SAST","SBT","SCT","SLT","SST","SST","TAHT","THA","UTC","UYST","UYT","VET",
"VLAT","WAT","WEDT","WEST","WET","YAKT","YEKT","Z","A","M","N","Y","MSK"}
local pattern = { -- для распознавания дат, переданных одним строчным параметром
{"(-?%d%d%d%d?)[-%.%s/\\](%d%d)[-%.%s/\\](%d%d)", ["order"] = {3,2,1} }, -- yyyy mm dd
{"(%d+)[-%.%s/\\](%d+)[-%.%s/\\](%d%d%d%d?)", ["order"] = {1,2,3} }, -- dd mm yyyy
{"(%d%d)[-%.%s/\\](%d%d%d%d?)", ["order"] = {2,3} }, -- mm yyyy
{"(%d%d%d%d?)[-%.%s/\\](%d%d)", ["order"] = {3,2} }, -- yyyy mm
{"(%d+)%s(%l+)%s(%d%d%d%d?)", ["order"] = {1,2,3} }, -- d mmm y
{"(%l+)%s(%d+),?%s(%d%d%d%d?)", ["order"] = {2,1,3} }, -- mmm d, y
{"(%l+)%s(%d%d%d%d?)", ["order"] = {2,3} }, -- mmm y
}
local time_units = {"year","month","day"} --не используется
--[[ local time_units = {"second", "minute", "hour",
"day_of_month", "day_of_week", "day_of_year",
"week", "month", "year", "year_of_century", "century"} ]]--
-- напоминание чтобы сделать более точные пересчёты - с часами / расчёт длительностей периодов
local mnlang = {"ru_G", "ru_N", "en", "en_S", "de", "fr"}
local month_lang = {
["ru_G"] = {"января","февраля","марта","апреля","мая","июня",
"июля","августа","сентября","октября","ноября","декабря"},
["ru_N"] = {"январь","февраль","март","апрель","май","июнь",
"июль","август","сентябрь","октябрь","ноябрь","декабрь"},
["en"] = {"january", "february", "march", "april", "may", "june",
"july", "august", "september", "october", "november", "december"},
["en_S"] = {"jan", "feb", "mar", "apr", "may", "jun",
"jul", "aug", "sep", "oct", "nov", "dec"},
["de"] = {"januar", "februar", "märz", "april", "mai", "juni",
"juli", "august", "september", "oktober", "november", "dezember"},
["fr"] = {"janvier", "février", "mars", "avril", "mai", "juin",
"juillet", "août", "septembre", "octobre", "novembre", "décembre"}
}
-- заполняется автоматически
local reverse_month_lang = {}
-- вспомогательная функция для обращения таблиц (смена ключей со значениями)
local reverse_table = function (strait_table)
local reversed_table = {}
for k,v in pairs(strait_table) do
reversed_table[v] = k
end
return reversed_table
end
-- запуск цикла по заполнению обратных таблиц, необходимых для распознавания дат
local filling_months = function (mnlang, month_lang)
for i=1, #mnlang do
reverse_month_lang[mnlang[i]] = reverse_table(month_lang[mnlang[i]])
end
end
-- 10) Блок общих функций
local function trim(str)
if not str then return nil
else return str:match'^()%s*$' and '' or str:match'^%s*(.*%S)'
end
end
local function purif(str)
if str == "" or str == nil then
return nil
elseif type(tonumber(str)) == "number" then
return math.floor(tonumber(str))
else
return nil
end
-- need .5 -- ,5 number format converter?
end
local function is(str)
if (not str) or (str == "") then return false
else return yesno(str,false)
end
end
local function init(num)
local output = {}
for i=1,num do
table.insert(output, {["year"]="", ["month"]="", ["day"]=""})
end
return unpack(output)
end
local function isyear(tbl)
if type(tbl) ~= 'table' then return false
elseif not tbl["year"] then return false
elseif type(tbl["year"]) == 'number' then return true
else return false
end
end
local function inbord(val, down, up)
return not (type(up) ~= "number" or type(down) ~= "number" or type(val) ~= "number" or up < down or val < down or val > up)
end
local function shallowcopy(orig)
local orig_type = type(orig)
local copy
if orig_type == 'table' then
copy = {}
for orig_key, orig_value in pairs(orig) do
copy[orig_key] = orig_value
end
else -- number, string, boolean, etc
copy = orig
end
return copy
end
local inlist = function ( var, list )
local n = #list
local inlist = false
for i=1,n do
if var == list[i] then inlist = true end
end
return inlist
end
-- 20) Блок общих проверочных функций, связанных с датами
local function unwarp(tbl)
if not tbl then return ""
elseif type(tbl) ~= "table" then return tbl
elseif (tbl.day or tbl.month or tbl.year) then
return (tbl.year or "?").."-"..(tbl.month or "?").."-"..(tbl.day or "?")
else return (tbl[3] or "?").."-"..(tbl[2] or "?").."-"..(tbl[1] or "?")
end
end
local function leap_year(y,jul)
if (not y) or (type(y) ~= "number")
then return false
elseif (y % 4) ~= 0
then return false
elseif not jul and (y % 100 == 0 and y % 400 ~= 0)
then return false
else return true
end
end
-- функция для вычисления последнего дня месяца для юлианского и григорианского календарей
local function month_end_day (month,year,is_julian)
local month_end_day = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} -- если не задан год, дата 29 февраля считается допустимой
if not month or type(month) ~= "number" or month < 1 or month > 12 then return nil
elseif month ~= 2 or not year then return month_end_day[month]
elseif month == 2 and (year % 4) == 0 and not ((not is_julian) and (year % 100 == 0 and year % 400 ~= 0)) then return 29
elseif month == 2 then return 28
else return nil -- в случае не целого значения входящих параметров или при иных непредусмотренных событиях
end
end
local function isdate ( chain , jul ) -- можно использовать для проверки таблиц с полями day, month, year
if not chain then return false
elseif (not type(chain) == "table")
or (not inbord(chain.year,-9999,9999))
or (not inbord(chain.month,1,12))
or (not inbord(chain.day,1,31))
or chain.day > monthd[chain.month]
-- or chain.year == 0
then return false
elseif chain.month == 2 and chain.day == 29 and not leap_year(chain.year,jul)
then return false
else return true end
-- check for other calendars needed?
end
local function ispartdate ( chain )
if not chain then return false
elseif not (type(chain) == "table") then return false
elseif (inbord(chain.year,-9999,9999)
or inbord(chain.month,1,12)
or inbord(chain.day,1,31)) then return true
else return false
end
-- partial date
-- more detailed check for 31.02.0000 needed
-- check for other calendars needed
end
-- from date1 to date2 in one year (beetwen jan-dec, dec-jan needed)
local function partdist(date1,date2)
local mont, dist = 0, 0
local d1d, d1m, d2d, d2m = (date1["day"] or ""), (date1["month"] or ""),(date2["day"] or ""), (date2["month"] or "")
if not (inbord(d1d,1,31) and inbord(d2d,1,31)) then return false end
-- нужна доп. проверка частичных дат на корректность
if (inbord(d1m,1,12) or inbord(d2m,1,12))
and (d1m == "" or d2m == "") then
mont = purif(date1["month"] or date2["month"])
d1m, d2m = mont, mont
end
-- mw.log("📏 day: " ..d1d .."->"..d2d.." month: ".. d1m.."->"..d2m )
if (inbord(d1m,1,12) and d1d <= monthd[d1m])
and (inbord(d2m,1,12) and d2d <= monthd[d2m]) then
if d2m == d1m
then dist = d2d - d1d
else dist = monthd[d1m] - d1d + d2d
end
return dist
else return math.huge
end
end
local function dmdist(d1,d2)
local p1,p2 = math.huge,math.huge
if not not partdist(d1,d2) then
p1=partdist(d1,d2)
end
if not not partdist(d2,d1) then
p1=partdist(d2,d1)
end
-- if (not p1) or (not p2) then
-- return (p1 or "") .. (p2 or "")
-- else
-- mw.log("d1, d2 = " .. undate(d1) .. ", " .. undate(d2))
return math.min(tonumber(partdist(d1,d2)) or math.huge,tonumber(partdist(d2,d1)) or math.huge)
-- end
end
-- 30) Блок функций для обработки ввода-вывода дат
local function undate(tbl)
if not tbl then return ""
else return (tbl.year or "").."-"..(tbl.month or "").."-"..(tbl.day or "")
end
end
-- функция для нормализации значений дат и перевода месяцев в числа
local function numerize(str)
if type(str) == "number" then
return math.floor(str)
elseif str == "" or str == nil or type(str) ~= "string" then
return nil
elseif type(tonumber(str)) == "number" then
return math.floor(tonumber(str))
else
for i=1, #mnlang do
if inlist(mw.ustring.lower(str),month_lang[mnlang[i]]) then
return reverse_month_lang[mnlang[i]][mw.ustring.lower(str)]
end
end
end
end
-- функция распознавания даты, переданной одной строкой
local function parse_date(date_string)
if type(date_string) ~= "string" or date_string == "" then return nil end
local out_date_str = {"","",""}
local error_data = {}
for i=1, #pattern do
local result_1, result_2, result_3 = mw.ustring.match(mw.ustring.lower(date_string),pattern[i][1])
if (result_1 or "") > "" then
out_date_str[pattern[i].order[1]] = result_1
out_date_str[pattern[i].order[2]] = result_2
if (pattern[i].order[3]) then out_date_str[pattern[i].order[3]] = result_3 end
-- mw.log("Паттерн " .. i .. ", строка: " .. date_string)
break
end
end
local date = {
["day"] =numerize(out_date_str[1]),
["month"]=numerize(out_date_str[2]),
["year"] =numerize(out_date_str[3])}
return date --, error_data
end
----[[ УСТАРЕЛО ]]----
local numstr2date = function(numstr)
local format = "Y-m-d"
local iso_date = mwlang:formatDate(format,numstr)
local y,m,d = string.match(iso_date, "(%d+)-(%d+)-(%d+)")
local dateout = {["year"]=purif(y), ["month"]=purif(m), ["day"]=purif(d)}
return dateout
end
--local numstr2date = function(numstr)
-- local nums = {}
-- local dateout = {}
-- for num in string.gmatch(numstr,"(%d+)") do
-- table.insert(nums,purif(num))
-- end
-- if #nums ~= 3 then error("В поле даты вместо трёх чисел с разделителями указано " .. #nums)
-- elseif not inbord(nums[2],1,12) then error("Месяц с номером " .. nums[2] .. " не найден")
-- elseif not inbord(nums[3],1,31) then
-- dateout = {["year"]=nums[3], ["month"]=nums[2], ["day"]=nums[1]}
-- elseif not inbord(nums[1],1,31) then
-- dateout = {["year"]=nums[1], ["month"]=nums[2], ["day"]=nums[3]}
-- elseif inbord(nums[1],1,31) then
-- dateout = {["year"]=nums[3], ["month"]=nums[2], ["day"]=nums[1]}
-- else
-- local mwlang = mw.getContentLanguage()
-- implement mwlang:formatDate(format,datein,true) here
-- return error("Не распознано " .. numstr .. " как дата")
-- end
-- return dateout
--end
local function year2lang(numyear,yearmark,wiki)
if not numyear then return "" end
if not yearmark then yearmark = "" end
local output = ""
local bcmark = " до н. э."
if numyear > 0 then bcmark = ""
else numyear = 1 - numyear end
if wiki then
-- output = tCon({'[[', numyear,' год',bcmark,'|', numyear,']]', " ", yearmark, " ", bcmark})
output = tCon({'[[', numyear,' год',bcmark,'|', trim(numyear .. " " .. yearmark .. " " .. bcmark), ']]'})
else
output = tCon({numyear, " ", yearmark, bcmark})
end
return trim(output)
end
local function day2lang(datein,wikidate,wiki,inner_brt)
-- if not isdate(wikidate) then wiki = false end
if not ispartdate(datein) then return "" end
local dm_separ, output = "", nil
if (not (not datein.day)) and (not (not datein.month)) then dm_separ = " " end
if (not datein.month) then datein.month = "" end
if (not datein.day) then datein.day = "" end
local monlan = monthlang[datein.month] or ""
if wiki and not inner_brt then
output = tCon({"[[", wikidate.day, " ", monthlang[wikidate.month] or "",
"|", (datein.day or ""), dm_separ, monlan, "]]"})
elseif wiki then
output = tCon({"[[", wikidate.day, " ", monthlang[wikidate.month] or "",
"|", (datein.day or ""), dm_separ, monlan})
else
output = tCon({datein.day, dm_separ, monlan})
end
return trim(output)
end
local function triple_txt2date(d,m,y)
-- добавить (args[1]:match("(%a+)") or "-") для нестандартной записи
-- mw.ustring.match((m or ""),"(%a+)")
local msg = ""
local year = purif((y or "-"):match("(%d+)"))
local month = purif(month_to_num[string.lower(mw.ustring.match((m or ""),"(%a+)"))])
local day = purif((d or "-"):match("(%d+)"))
if not month then
msg = category.incomplete_parameters
month = purif(month_to_num[string.lower(mw.ustring.match((d or ""),"(%a+)") or "-")])
end
if (not day) and ((purif(string.match(m or "","(%d+)") or "") or 32) <= (monthd[month] or 31)) then
msg = category.incomplete_parameters
day = purif(m:match("(%d+)") or "")
end
if not year then
msg = category.incomplete_parameters
year = purif(string.match(m or "","(%d+)") or "")
end
local dateout = {["year"]=year, ["month"]=month, ["day"]=day, ["msg"]=msg}
return dateout
end
local function glue(d1,m1,y1,d2,m2,y2)
if (not d1) and (not m1) and (not y1) and (not d2) and (not m2) and (not y2) then
return category.incomplete_parameters end
local gd,gm,gy,jd,jm,jy =
(d1 or ""),
(m1 or ""),
(y1 or ""),
(d2 or ""),
(m2 or ""),
(y2 or "")
--mw.log(tCon({gd,gm,gy,jd,jm,jy}))
local gm_sep = {" [["," год|","]]"}
if (not gy) or (gy == "") then gm_sep = {"","",""} end
return tCon({comment[1],trim(trim(jd .. " " .. jm) .. " " .. jy ),
comment[2]," ([[",trim(gd .. " " .. gm),"]]",gm_sep[1],(gy:match("(%d+)") or ""),
gm_sep[2],gy,gm_sep[3],")",category.incomplete_parameters})
end
-- добавить отображение без года
local function double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark)
local msg = ""
msg = (jdate.msg or "") .. (gdate.msg or "")
local cd = {}
local jd = shallowcopy(jdate)
local gd = shallowcopy(gdate)
local left = "("
local right = ")"
if sq_brts then
left = "["
right = "]"
end
if (not isdate(jdate,true)) then return error((jdate.day or "") .. "." .. (jdate.month or "") .."." .. (jdate.year or "") .. " неподходящая дата")
elseif (not isdate(gdate)) then return error((gdate.day or "") .. "." .. (gdate.month or "") .."." .. (gdate.year or "") .. " неподходящая дата") end
if jd.year == gd.year then
cd.year = gd.year
gd.year, jd.year = nil, nil
end
if jd.month == gd.month then
cd.month = gd.month
gd.month, jd.month = nil, nil
end
if (not not cd.month) and wm then
return tCon({comment[1] .. trim(day2lang(jd,jdate,false) .. " " .. year2lang(jd.year,yearmark,false)) .. comment[2],
trim(left .. day2lang(gd,gdate,wd,wm) .. " " .. year2lang(gd.year,yearmark,wy)) .. right,
day2lang(cd,gdate,false) .. "]]", trim(year2lang(cd.year,yearmark,wy)..msg)}, " ")
end
return tCon({comment[1] .. trim(day2lang(jd,jdate,false) .. " " .. year2lang(jd.year,yearmark,false)) .. comment[2],
trim(left .. day2lang(gd,gdate,wd) .. " " .. year2lang(gd.year,yearmark,wy)) .. right,
trim(day2lang(cd,gdate,false)), trim(year2lang(cd.year,yearmark,wy)..msg)}, " ")
end
-- 40) Блок функций для перевода дат с использованием [[Юлианская дата]]
local function gri2jd( datein )
if not isdate(datein) then return error((datein.day or "") .. "." .. (datein.month or "") .."." .. (datein.year or "") .. " неподходящая дата") end
local year = datein.year
local month = datein.month
local day = datein.day
-- jd calculation
local a = math.floor((14 - month)/12)
local y = year + 4800 - a
local m = month + 12*a - 3
local offset = math.floor(y/4) - math.floor(y/100) + math.floor(y/400) - 32045
local jd = day + math.floor((153*m + 2)/5) + 365*y + offset
-- jd validation
local low, high = -1931076.5, 5373557.49999
if not (low <= jd and jd <= high) then
return error((datein.day or "") .. "." .. (datein.month or "") .. "." .. (datein.year or "") .. " выходит за пределы разрешённого диапазона")
end
return jd
end
local function jd2jul( jd )
if type(jd) ~= "number" then return error("Промежуточная переменная " .. (jd or "") .. " не является числом") end
-- calendar date calculation
local c = jd + 32082
local d = math.floor((4*c + 3)/1461)
local e = c - math.floor(1461*d/4)
local m = math.floor((5*e + 2)/153)
local year_out = d - 4800 + math.floor(m/10)
local month_out = m + 3 - 12*math.floor(m/10)
local day_out = e - math.floor((153*m + 2)/5) + 1
-- output
local dateout = {["year"]=year_out, ["month"]=month_out, ["day"]=day_out}
return dateout
end
local function jul2jd( datein )
if not isdate(datein,true) then return error((datein.day or "") .. "." .. (datein.month or "") ..".".. (datein.year or "") .. " неподходящая дата") end
local year = datein.year
local month = datein.month
local day = datein.day
-- jd calculation
local a = math.floor((14 - month)/12)
local y = year + 4800 - a
local m = month + 12*a - 3
local offset = math.floor(y/4) - 32083
local jd = day + math.floor((153*m + 2)/5) + 365*y + offset
-- jd validation
local low, high = -1930999.5, 5373484.49999
if not (low <= jd and jd <= high) then
return error((datein.day or "") .. "." .. (datein.month or "") .."." .. (datein.year or "") .. " выходит за пределы разрешённого диапазона")
end
return jd
end
local function jd2gri( jd )
if type(jd) ~= "number" then return error("Промежуточная переменная " .. (jd or "") .. " не является числом") end
-- calendar date calculation
local a = jd + 32044
local b = math.floor((4*a + 3) / 146097)
local c = a - math.floor(146097*b/4)
local d = math.floor((4*c+3)/1461)
local e = c - math.floor(1461*d/4)
local m = math.floor((5*e+2)/153)
local day_out = e - math.floor((153*m+2)/5)+1
local month_out = m + 3 - 12*math.floor(m/10)
local year_out = 100*b + d - 4800 + math.floor(m/10)
-- output
local dateout = {["year"]=year_out, ["month"]=month_out, ["day"]=day_out}
return dateout
end
local function astroyear(num, bc)
if not num then return error()
elseif type(num) ~= "number" then return error()
end
if num < 1 then return num end
if not bc then return num
else return 1 - num
end
end
local function recalc(datein,calend)
if inlist(calend,params[1]) then
return jd2jul(gri2jd(datein)), datein
elseif inlist(calend,params[2]) then
return datein, jd2gri(jul2jd(datein))
else error("Параметр " .. (calend or "") .. " не опознан, разрешённые: " .. tCon(params[1]," ") .. " и " .. tCon(params[2]," "))
end
end
-- 50) Функции для обработки UTC
local function utc(str,margin)
local d = 1
local dchar = "+"
local beginning = "[[UTC"
local ending = "]]"
local cat = ""
local nums = {}
local hmarg, timedec = 0, 0
local mmarg = "00"
local output = ""
-- checking type of input
if not margin then margin = 0
elseif type(tonumber(margin)) ~= 'number' then
output = "Can't shift by " .. margin
error(output)
end
if type(str) ~= 'string' then
error("Нет входящей строки")
elseif str:byte(1) == 43 then
elseif inbord(str:byte(1),48,57) then cat = "[[Категория:Википедия:Ошибка в часовом поясе НП]]"
elseif str:byte(1) == 45 or string.sub(str,1,3) == "−" or string.sub(str,1,1)=="-" then d = -1
else
error(string.char(str:byte(1)) .. " недопустимый первый символ")
end
-- parsing input
for num in string.gmatch(str,"(%d+)") do
table.insert(nums,purif(num))
end
if #nums > 2 then error("Ожидается всего 2 числа, а не " .. #nums)
elseif #nums == 0 then error("Необходимо что-то ввести")
elseif #nums == 1 then
if inbord(nums[1],0,14) then timedec = d*nums[1] + margin
else error("Только часы от -14 до 14") end
elseif #nums == 2 then
if not inbord(nums[1],0,14) then error("Только часы от -14 до 14")
elseif not inbord(nums[2],0,59) then error("Минуты только от 0 до 59")
else
timedec = d*(nums[1] + nums[2]/60) + margin
end
end
if tonumber(timedec) == purif(timedec) then hmarg = timedec
else
local h, m = math.modf(math.abs(timedec))
hmarg = h
mmarg = math.floor(m*60)
end
if timedec == 0 then
dchar = "±"
elseif timedec > 0 then
elseif timedec < 0 then
dchar = "−"
end
-- output
output = beginning .. dchar .. math.abs(hmarg) .. ":" .. string.format("%02d",mmarg) .. ending .. cat
return output
end
-- 60) Блок функций ввода-вывода
function p.NthDay( frame )
local args = getArgs(frame, { frameOnly = true })
local num, wday, mont, yea, format =
purif(args[1]), purif(args[2]), purif(args[3]), purif(args[4]), args[5]
if not format then format = "%d.%m.%y" end
if not inbord(num,-5,5) then
return error("The number must be between -5 and 5")
elseif num == 0 then
return error("The number must not be zero") end
if not inbord(wday,0,6) then
return error("The day of the week must be between 0 and 6") end
if not inbord(mont,1,12) then
return error("The month must be between 1 and 12") end
if not inbord(yea,0,9999) then
return error("Wrong year number") end
if inbord(num,1,5) then
local m_start = os.time{year=yea, month=mont, day=1, hour=0}
local m_wds = tonumber(os.date("%w", m_start))
local start_shift = (
(num - bool_to_number[wday >= m_wds]) * 7
- (m_wds - wday)
) * 24 * 60 * 60
local tim = m_start + start_shift
if tonumber(os.date("%m", tim)) == mont then
return (os.date(format, tim))
else
return (err)
end
elseif inbord(num,-5,-1) then
local m_end = os.time{year = yea, month = mont + 1, day = 1, hour = 0} - 24 * 60 * 60
local m_wde = tonumber(os.date("%w", m_end))
local end_shift = ((math.abs(num + 1) + bool_to_number[wday > m_wde]) * 7
+ (m_wde - wday)) * 24 * 60 * 60
local tim = m_end - end_shift
if tonumber(os.date("%m", tim)) == mont then
return (os.date(format, tim))
else
return (err)
end
end
end
-- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"12 декабря 2020"}})
-- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"1.2.1602"}})
-- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"12.12.2021"}})
-- =p.ToIso(mw.getCurrentFrame():newChild{title="smth",args={"2021.12.12"}})
function p.ToIso( frame )
local args = getArgs(frame, { frameOnly = true })
local datein = args[1]
-- инициализация, заполнение обратных таблиц, копирование параметров
filling_months(mnlang, month_lang)
-- парсинг входящей даты по шаблону
local date = parse_date(datein)
if not (type(date.year) == 'number') then
return ("Wrong year: " .. unwarp(date))
end
if not (1 <= date.month and date.month <= 12) then
return ("Wrong month: " .. unwarp(date))
end
if not date.day or not (1 <= date.day and date.day <= month_end_day(date.month,date.year)) then
return ("Wrong day: " .. unwarp(date))
end
local timedate = os.time{year=date.year, month=date.month, day=date.day}
local date = os.date("%Y-%m-%d", timedate)
return date
end
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12 декабря 2020"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"1.2.1602"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"декабрь 2020"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12-2020"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"12.12.2021"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"2021.12.12"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"2021.11"}})
-- =p.BoxDate(mw.getCurrentFrame():newChild{title="smth",args={"11.2021"}})
function p.BoxDate( frame )
local args = getArgs(frame, { frameOnly = true })
local txtDateIn, strFormat = args[1], args[2]
local txtDateOut, date, status = p.bxDate(txtDateIn, strFormat, params)
if status.brk then
return error(status.errorText)
else
return txtDateOut
end
end
function p.bxDate( txtDateIn , strFormat, params ) -- к отладке
local txtDateOut, date, status = "", {}, {brk = false, errorCat = "", errorText = ""}
strFormat = strFormat or "j xg Y"
-- заглушка - таблица параметров на будущее
params = params or {}
if not txtDateIn then
status.errorText = e.no_data
status.errorCat = category.no_parameters
status.brk = true
else
-- заполнение служебных таблиц
filling_months(mnlang, month_lang)
end
if not status.brk then
-- парсинг входящей даты по шаблону
date = parse_date(txtDateIn)
-- заменить сообщения об ошибках на списочные
if not (date.year and type(date.year) == 'number') then
status.errorText = string.format(e.box_date,txtDateIn)
status.errorCat = category.incomplete_parameters
status.brk = true
end
if not inbord(date.month,1,12) then
status.errorText = string.format(e.box_date,txtDateIn)
status.errorCat = category.incomplete_parameters
status.brk = true
end
if not date.day and string.find(strFormat,"[dDjlNwzW]") then
strFormat = trim(string.gsub(string.gsub(strFormat,"xg","F"),"[dDjlNwzW]",""))
elseif not date.day then
elseif not inbord(date.day,1,month_end_day(date.month,date.year)) then
status.errorText = string.format(e.box_date,txtDateIn)
status.errorCat = category.incomplete_parameters
status.brk = true
end
end
if not status.brk then
txtDateOut = mwlang:formatDate(strFormat,tCon({date.year,date.month,date.day},"-"),true)
end
return txtDateOut, date, status
end
function p.ToDate( frame ) -- возможно неиспользуемая
local args = getArgs(frame, { frameOnly = true })
local mwlang = mw.getContentLanguage()
local datein = args[1]
local format = "j xg Y"
if not string.match(datein, "%p") then return datein
elseif not args[2] then
else format = args[2]
end
return mwlang:formatDate(format,datein,true)
end
-- =p.unitime(mw.getCurrentFrame():newChild{title="smth",args={"−1:30","1"}})
function p.unitime( frame )
local args = getArgs(frame, { frameOnly = true })
local DST = 0
if not args[2] then
else DST = 1 end
local utcin = ""
local input = args[1]
if not input then return "" end
if inlist(input:upper(),tzs_names) then
utcin = known_tzs[input:upper()]
elseif (string.sub(input:upper(),1,3) == 'UTC') and (string.len(input) < 10) then
utcin = string.sub(input,4)
else
if string.sub(input,1,1) == '['
or string.sub(input,1,1) == '{'
or string.sub(input,1,1):upper() == 'U'
or string.sub(input,1,1):upper() == 'M' then
return input
-- elseif not string.find(string.upper(string.sub(input,1,1)),"[\65-\90]") or
-- not string.find(string.upper(string.sub(input,1,1)),"[\192-\223]") then
-- return input
else utcin = input end
end
-- elseif string.sub(input,1,3) ~= "−" then utcin = input
-- or not (not input:find("[А-я]")) при наличии в строке юникода не работает
local output = ""
if DST == 0 then output = utc(utcin)
else output = utc(utcin) .. ", [[летнее время|летом]] " .. utc(utcin,DST)
end
return output
end
-- УСТАРЕЛО
-- =p.OldDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020","ю",["bc"]="1",["wd"]="1",["wy"]="1",["sq_brts"]="1",["yearmark"]="г."}})
function p.OldDate( frame )
local args = getArgs(frame, { frameOnly = true })
if not args[1] then return err end
local gdate, jdate = {}, {}
local strin = args[1]
local cal = args[2]:lower() or "г"
local bc = is(args["bc"])
local wd = is(args["wd"])
local wm = is(args["wm"])
local wy = is(args["wy"])
if not wd then wm = false end
local sq_brts = is(args["sq_brts"])
local yearmark = "года"
if yesno(args["yearmark"]) then
elseif yesno(args["yearmark"]) == false then yearmark = ""
else yearmark = trim(args["yearmark"]) or "года" end
-- local infocard = is(args["infocard"])
-- local catName = args["catName"] or false
local datein = numstr2date(strin)
datein.year = astroyear(datein.year, bc)
jdate, gdate = recalc(datein,cal)
return double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark)
end
-- =p.NewDate(mw.getCurrentFrame():newChild{title="Salt",args={"2020-02-20"}})
-- =p.NewDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020","ю",["bc"]="1",["wd"]="1",["wy"]="1",["sq_brts"]="1",["yearmark"]="г."}})
-- =p.NewDate(mw.getCurrentFrame():newChild{title="smth",args={"20.02.2020",["bc"]="0",["wd"]="1",["wy"]="1",["sq_brts"]="0",["yearmark"]=""}})
function p.NewDate( frame )
local args = getArgs(frame, { frameOnly = true })
if not args[1] then return err end
local strin = args[1]
local year, month, day
if not not strin:match( "(-?%d%d%d%d%d)-(%d%d)-(%d%d)" ) then
year, month, day = strin:match( "(-?%d%d%d%d%d)-(%d%d)-(%d%d)" )
elseif not not strin:match( "(-?%d+)-(%d+)-(%d+)" ) then
year, month, day = strin:match( "(-?%d+)-(%d+)-(%d+)" )
elseif not not strin:match( "(%d%d)%.(%d%d)%.(-?%d%d%d%d%d)" ) then
day, month, year = strin:match( "(%d%d)%.(%d%d)%.(-?%d%d%d%d%d)" )
elseif not not strin:match( "(%d+)%.(%d+)%.(-?%d+)" ) then
day, month, year = strin:match( "(%d+)%.(%d+)%.(-?%d+)" )
end
if not year then return error(args[1] .. " не подходит под форматы yyyy-mm-dd или dd.mm.yyyy")
end
local cal = "г"
if (not args[2]) or (args[2] == "") then cal = "г"
else cal = args[2]:lower() end
local bc,wd,wm,wy,sq_brts =
is(args["bc"]),
is(args["wd"]),
is(args["wd"]) and is(args["wm"]),
is(args["wy"]),
is(args["sq_brts"])
year = astroyear(purif(year),bc)
local datein = {["year"]=purif(year), ["month"]=purif(month), ["day"]=purif(day)}
local jdate, gdate = recalc(datein,cal)
local yearmark = "года"
local ym = args["yearmark"] or ""
if yesno(ym) then
elseif yesno(ym) == false then yearmark = ""
else
if not not ym:match("(%d+)") then
error("Цифры в обозначении года: " .. ym)
else yearmark = trim(ym) or "года" end
end
return double_couple(jdate, gdate, wd, wm, wy, sq_brts, yearmark)
end
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"3","июня",nil,"21","мая"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28 августа","","1916 года","15"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"3","июня","1900","21","мая"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"6","июня","1889 год","25","мая"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28","ноября","1917","15"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"28 августа","nil","1916 года","15"}})
-- =p.Test(mw.getCurrentFrame():newChild{title="smth",args={"4","января","1915","22","декабря","1914 года"}})
-- {{OldStyleDate|день (НС)|месяц (НС)|год (НС)|день (СС)|месяц (СС)|год (СС)}}
function p.Test( frame )
local args = getArgs(frame, { frameOnly = true })
-- необходима проверка и замена nil на " "
--[[mw.log((args[1] or "") .. " " ..
(args[2] or "") .. " " ..
(args[3] or "") .. " " ..
(args[4] or "") .. " " ..
(args[5] or "") .. " " ..
(args[6] or "")) ]]--
local ingdate = triple_txt2date(args[1],args[2],args[3])
local injdate = triple_txt2date(args[4],args[5],args[6])
local j1date, g1date, j2date, g2date = init(4)
mw.log("ingdate-".. (undate(ingdate) or ""))
mw.log("injdate-".. (undate(injdate) or ""))
local bc,wd,wm,wy,sq_brts,ny =
is(args["bc"]),
is(args["wd"]),
is(args["wd"]) and is(args["wm"]),
is(args["wy"]),
is(args["sq_brts"]),
is(args["ny"])
-- подавление формата для локальных тестов
local wd, wm, wy = true, true, true
local yearmark = "года"
local ym = args["yearmark"] or ((mw.ustring.match((args[3] or ""),"(%a+)") or mw.ustring.match((args[6] or ""),"(%a+)")) or "")
-- mw.log("ym " .. ym)
if yesno(ym) then
elseif yesno(ym) == false then yearmark = ""
else
if not not ym:match("(%d+)") then
error("Цифры в обозначении года: " .. ym)
else yearmark = trim(ym) or "года" end
end
if isdate(ingdate) or isdate(injdate) then
if isdate(ingdate) then
j1date, g1date = recalc(ingdate,"g")
ingdate["full"] = true
end
if isdate(injdate) then
j2date, g2date = recalc(injdate,"j")
injdate["full"] = true
end
if ispartdate(ingdate) and ispartdate(injdate) then
mw.log("📏 " .. dmdist(ingdate,injdate))
mw.log("📏 " .. dmdist(j1date,g1date))
mw.log("📏 " .. dmdist(j2date,g2date))
mw.log("📏 " .. dmdist(ingdate,g1date))
mw.log("📏 " .. dmdist(injdate,j2date))
end
end
if ny then
if isyear(j1date) then
else j1date["year"] = "" end
if isyear(j2date) == nil then
else j2date["year"] = "" end
if isyear(g1date) == nil then
else g1date["year"] = "" end
if isyear(g2date) == nil then
else g2date["year"] = "" end
end
if (isdate(j1date) and isdate(g1date) and isdate(j2date) and isdate(g2date)) then
if ((j1date.year == j2date.year)
and (j1date.month == j2date.month)
and (j1date.day == j2date.day)) then
return double_couple(j1date, g1date, wd, wm, wy, sq_brts, yearmark)
else
mw.log("📏 " .. (tostring(dmdist(ingdate,injdate)) or ""))
return glue(args[1],args[2],args[3],args[4],args[5],args[6])
-- категория (предположительная разница в днях) и частичный вывод
end
elseif isdate(j1date) and isdate(g1date) then
return double_couple(j1date, g1date, wd, wm, wy, sq_brts, yearmark) -- категория плюс частичная проверка
elseif isdate(j2date) and isdate(g2date) then
return double_couple(j2date, g2date, wd, wm, wy, sq_brts, yearmark) -- категория плюс частичная проверка
elseif (ispartdate(ingdate) and ispartdate(injdate)) then
mw.log("ingdate ".. (undate(ingdate) or ""))
mw.log("injdate ".. (undate(injdate) or ""))
mw.log("j1date " .. (undate(j1date ) or ""))
mw.log("j2date " .. (undate(j2date ) or ""))
mw.log("g1date " .. (undate(g1date ) or ""))
mw.log("g2date " .. (undate(g2date ) or ""))
mw.log("📏 " .. (tostring(partdist(ingdate,injdate)) or "").. " — " .. (tostring(partdist(injdate,ingdate)) or ""))
return glue(args[1],args[2],args[3],args[4],args[5],args[6])
-- частичный или полный вывод, категория
else
mw.log("ingdate ".. (undate(ingdate) or ""))
mw.log("injdate ".. (undate(injdate) or ""))
mw.log("j1date " .. (undate(j1date ) or ""))
mw.log("j2date " .. (undate(j2date ) or ""))
mw.log("g1date " .. (undate(g1date ) or ""))
mw.log("g2date " .. (undate(g2date ) or ""))
return err .. category.incomplete_parameters
end
end
return p
a4a91f134ad3e3b246b3a6681a4ae438da766df4
Модуль:Category handler
828
31
614
415
2024-08-16T16:22:38Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
--------------------------------------------------------------------------------
-- --
-- CATEGORY HANDLER --
-- --
-- This module implements the {{category handler}} template in Lua, --
-- with a few improvements: all namespaces and all namespace aliases --
-- are supported, and namespace names are detected automatically for --
-- the local wiki. This module requires [[Module:Namespace detect]] --
-- and [[Module:Yesno]] to be available on the local wiki. It can be --
-- configured for different wikis by altering the values in --
-- [[Module:Category handler/config]], and pages can be blacklisted --
-- from categorisation by using [[Module:Category handler/blacklist]]. --
-- --
--------------------------------------------------------------------------------
-- Load required modules
local yesno = require('Module:Yesno')
-- Lazily load things we don't always need
local mShared, mappings
local p = {}
--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------
local function trimWhitespace(s, removeBlanks)
if type(s) ~= 'string' then
return s
end
s = s:match('^%s*(.-)%s*$')
if removeBlanks then
if s ~= '' then
return s
else
return nil
end
else
return s
end
end
--------------------------------------------------------------------------------
-- CategoryHandler class
--------------------------------------------------------------------------------
local CategoryHandler = {}
CategoryHandler.__index = CategoryHandler
function CategoryHandler.new(data, args)
local obj = setmetatable({ _data = data, _args = args }, CategoryHandler)
-- Set the title object
do
local pagename = obj:parameter('demopage')
local success, titleObj
if pagename then
success, titleObj = pcall(mw.title.new, pagename)
end
if success and titleObj then
obj.title = titleObj
if titleObj == mw.title.getCurrentTitle() then
obj._usesCurrentTitle = true
end
else
obj.title = mw.title.getCurrentTitle()
obj._usesCurrentTitle = true
end
end
-- Set suppression parameter values
for _, key in ipairs{'nocat', 'categories'} do
local value = obj:parameter(key)
value = trimWhitespace(value, true)
obj['_' .. key] = yesno(value)
end
do
local subpage = obj:parameter('subpage')
local category2 = obj:parameter('category2')
if type(subpage) == 'string' then
subpage = mw.ustring.lower(subpage)
end
if type(category2) == 'string' then
subpage = mw.ustring.lower(category2)
end
obj._subpage = trimWhitespace(subpage, true)
obj._category2 = trimWhitespace(category2) -- don't remove blank values
end
return obj
end
function CategoryHandler:parameter(key)
local parameterNames = self._data.parameters[key]
local pntype = type(parameterNames)
if pntype == 'string' or pntype == 'number' then
return self._args[parameterNames]
elseif pntype == 'table' then
for _, name in ipairs(parameterNames) do
local value = self._args[name]
if value ~= nil then
return value
end
end
return nil
else
error(string.format(
'invalid config key "%s"',
tostring(key)
), 2)
end
end
function CategoryHandler:isSuppressedByArguments()
return
-- See if a category suppression argument has been set.
self._nocat == true
or self._categories == false
or (
self._category2
and self._category2 ~= self._data.category2Yes
and self._category2 ~= self._data.category2Negative
)
-- Check whether we are on a subpage, and see if categories are
-- suppressed based on our subpage status.
or self._subpage == self._data.subpageNo and self.title.isSubpage
or self._subpage == self._data.subpageOnly and not self.title.isSubpage
end
function CategoryHandler:shouldSkipBlacklistCheck()
-- Check whether the category suppression arguments indicate we
-- should skip the blacklist check.
return self._nocat == false
or self._categories == true
or self._category2 == self._data.category2Yes
end
function CategoryHandler:matchesBlacklist()
if self._usesCurrentTitle then
return self._data.currentTitleMatchesBlacklist
else
mShared = mShared or require('Module:Category handler/shared')
return mShared.matchesBlacklist(
self.title.prefixedText,
mw.loadData('Module:Category handler/blacklist')
)
end
end
function CategoryHandler:isSuppressed()
-- Find if categories are suppressed by either the arguments or by
-- matching the blacklist.
return self:isSuppressedByArguments()
or not self:shouldSkipBlacklistCheck() and self:matchesBlacklist()
end
function CategoryHandler:getNamespaceParameters()
if self._usesCurrentTitle then
return self._data.currentTitleNamespaceParameters
else
if not mappings then
mShared = mShared or require('Module:Category handler/shared')
mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData
end
return mShared.getNamespaceParameters(
self.title,
mappings
)
end
end
function CategoryHandler:namespaceParametersExist()
-- Find whether any namespace parameters have been specified.
-- We use the order "all" --> namespace params --> "other" as this is what
-- the old template did.
if self:parameter('all') then
return true
end
if not mappings then
mShared = mShared or require('Module:Category handler/shared')
mappings = mShared.getParamMappings(true) -- gets mappings with mw.loadData
end
for ns, params in pairs(mappings) do
for i, param in ipairs(params) do
if self._args[param] then
return true
end
end
end
if self:parameter('other') then
return true
end
return false
end
function CategoryHandler:getCategories()
local params = self:getNamespaceParameters()
local nsCategory
for i, param in ipairs(params) do
local value = self._args[param]
if value ~= nil then
nsCategory = value
break
end
end
if nsCategory ~= nil or self:namespaceParametersExist() then
-- Namespace parameters exist - advanced usage.
if nsCategory == nil then
nsCategory = self:parameter('other')
end
local ret = {self:parameter('all')}
local numParam = tonumber(nsCategory)
if numParam and numParam >= 1 and math.floor(numParam) == numParam then
-- nsCategory is an integer
ret[#ret + 1] = self._args[numParam]
else
ret[#ret + 1] = nsCategory
end
if #ret < 1 then
return nil
else
return table.concat(ret)
end
elseif self._data.defaultNamespaces[self.title.namespace] then
-- Namespace parameters don't exist, simple usage.
return self._args[1]
end
return nil
end
--------------------------------------------------------------------------------
-- Exports
--------------------------------------------------------------------------------
local p = {}
function p._exportClasses()
-- Used for testing purposes.
return {
CategoryHandler = CategoryHandler
}
end
function p._main(args, data)
data = data or mw.loadData('Module:Category handler/data')
local handler = CategoryHandler.new(data, args)
if handler:isSuppressed() then
return nil
end
return handler:getCategories()
end
function p.main(frame, data)
data = data or mw.loadData('Module:Category handler/data')
local args = require('Module:Arguments').getArgs(frame, {
wrappers = data.wrappers,
valueFunc = function (k, v)
v = trimWhitespace(v)
if type(k) == 'number' then
if v ~= '' then
return v
else
return nil
end
else
return v
end
end
})
return p._main(args, data)
end
return p
b74dd63857b24904ac452429b11213f18647471f
Модуль:Category handler/blacklist
828
75
616
123
2024-08-16T16:22:38Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
-- This module contains the blacklist used by [[Module:Category handler]].
-- Pages that match Lua patterns in this list will not be categorised unless
-- categorisation is explicitly requested.
return {
'^Main Page$', -- don't categorise the main page.
-- Don't categorise the following pages or their subpages.
-- "%f[/\0]" matches if the next character is "/" or the end of the string.
'^Wikipedia:Cascade%-protected items%f[/\0]',
'^User:UBX%f[/\0]', -- The userbox "template" space.
'^User talk:UBX%f[/\0]',
-- Don't categorise subpages of these pages, but allow
-- categorisation of the base page.
'^Wikipedia:Template messages/.*$',
'/[aA]rchive' -- Don't categorise archives.
}
c84948ad9808d5d323408d5d10d5652f748a0550
Модуль:Category handler/config
828
70
618
113
2024-08-16T16:22:39Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
--------------------------------------------------------------------------------
-- [[Module:Category handler]] configuration data --
-- Language-specific parameter names and values can be set here. --
-- For blacklist config, see [[Module:Category handler/blacklist]]. --
--------------------------------------------------------------------------------
local cfg = {} -- Don't edit this line.
--------------------------------------------------------------------------------
-- Start configuration data --
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Parameter names --
-- These configuration items specify custom parameter names. --
-- To add one extra name, you can use this format: --
-- --
-- foo = 'parameter name', --
-- --
-- To add multiple names, you can use this format: --
-- --
-- foo = {'parameter name 1', 'parameter name 2', 'parameter name 3'}, --
--------------------------------------------------------------------------------
cfg.parameters = {
-- The nocat and categories parameter suppress
-- categorisation. They are used with Module:Yesno, and work as follows:
--
-- cfg.nocat:
-- Result of yesno() Effect
-- true Categorisation is suppressed
-- false Categorisation is allowed, and
-- the blacklist check is skipped
-- nil Categorisation is allowed
--
-- cfg.categories:
-- Result of yesno() Effect
-- true Categorisation is allowed, and
-- the blacklist check is skipped
-- false Categorisation is suppressed
-- nil Categorisation is allowed
nocat = 'nocat',
categories = 'categories',
-- The parameter name for the legacy "category2" parameter. This skips the
-- blacklist if set to the cfg.category2Yes value, and suppresses
-- categorisation if present but equal to anything other than
-- cfg.category2Yes or cfg.category2Negative.
category2 = 'category2',
-- cfg.subpage is the parameter name to specify how to behave on subpages.
subpage = 'subpage',
-- The parameter for data to return in all namespaces.
all = 'all',
-- The parameter name for data to return if no data is specified for the
-- namespace that is detected.
other = 'other',
-- The parameter name used to specify a page other than the current page;
-- used for testing and demonstration.
demopage = 'page',
}
--------------------------------------------------------------------------------
-- Parameter values --
-- These are set values that can be used with certain parameters. Only one --
-- value can be specified, like this: --
-- --
-- cfg.foo = 'value name' -- --
--------------------------------------------------------------------------------
-- The following settings are used with the cfg.category2 parameter. Setting
-- cfg.category2 to cfg.category2Yes skips the blacklist, and if cfg.category2
-- is present but equal to anything other than cfg.category2Yes or
-- cfg.category2Negative then it supresses cateogrisation.
cfg.category2Yes = 'yes'
cfg.category2Negative = '¬'
-- The following settings are used with the cfg.subpage parameter.
-- cfg.subpageNo is the value to specify to not categorise on subpages;
-- cfg.subpageOnly is the value to specify to only categorise on subpages.
cfg.subpageNo = 'no'
cfg.subpageOnly = 'only'
--------------------------------------------------------------------------------
-- Default namespaces --
-- This is a table of namespaces to categorise by default. The keys are the --
-- namespace numbers. --
--------------------------------------------------------------------------------
cfg.defaultNamespaces = {
[ 0] = true, -- main
[ 6] = true, -- file
[ 12] = true, -- help
[ 14] = true, -- category
[100] = true, -- portal
[108] = true, -- book
}
--------------------------------------------------------------------------------
-- Wrappers --
-- This is a wrapper template or a list of wrapper templates to be passed to --
-- [[Module:Arguments]]. --
--------------------------------------------------------------------------------
cfg.wrappers = 'Template:Category handler'
--------------------------------------------------------------------------------
-- End configuration data --
--------------------------------------------------------------------------------
return cfg -- Don't edit this line.
373cd107b13a5b00e6a1b7e66a749f12502c849d
Модуль:Category handler/data
828
69
620
111
2024-08-16T16:22:39Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
-- This module assembles data to be passed to [[Module:Category handler]] using
-- mw.loadData. This includes the configuration data and whether the current
-- page matches the title blacklist.
local data = require('Module:Category handler/config')
local mShared = require('Module:Category handler/shared')
local blacklist = require('Module:Category handler/blacklist')
local title = mw.title.getCurrentTitle()
data.currentTitleMatchesBlacklist = mShared.matchesBlacklist(
title.prefixedText,
blacklist
)
data.currentTitleNamespaceParameters = mShared.getNamespaceParameters(
title,
mShared.getParamMappings()
)
return data
abbc68048ff698e88dda06b64ecf384bbf583120
Модуль:Category handler/shared
828
74
622
121
2024-08-16T16:22:39Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
-- This module contains shared functions used by [[Module:Category handler]]
-- and its submodules.
local p = {}
function p.matchesBlacklist(page, blacklist)
for i, pattern in ipairs(blacklist) do
local match = mw.ustring.match(page, pattern)
if match then
return true
end
end
return false
end
function p.getParamMappings(useLoadData)
local dataPage = 'Module:Namespace detect/data'
if useLoadData then
return mw.loadData(dataPage).mappings
else
return require(dataPage).mappings
end
end
function p.getNamespaceParameters(titleObj, mappings)
-- We don't use title.nsText for the namespace name because it adds
-- underscores.
local mappingsKey
if titleObj.isTalkPage then
mappingsKey = 'talk'
else
mappingsKey = mw.site.namespaces[titleObj.namespace].name
end
mappingsKey = mw.ustring.lower(mappingsKey)
return mappings[mappingsKey] or {}
end
return p
d2d5de1a031e6ce97c242cbfa8afe7a92cb9eca5
Модуль:Message box
828
21
624
137
2024-08-16T16:22:40Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
-- This is a meta-module for producing message box templates, including
-- {{mbox}}, {{ambox}}, {{imbox}}, {{tmbox}}, {{ombox}}, {{cmbox}} and {{fmbox}}.
-- Load necessary modules.
require('strict')
local getArgs
local categoryHandler = require('Module:Category handler')._main
local yesno = require('Module:Yesno')
local boxDate = require('Module:Calendar').bxDate;
-- Get a language object for formatDate and ucfirst.
local lang = mw.language.getContentLanguage()
-- Define constants
local CONFIG_MODULE = 'Module:Message box/configuration'
--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------
local function getTitleObject(...)
-- Get the title object, passing the function through pcall
-- in case we are over the expensive function count limit.
local success, title = pcall(mw.title.new, ...)
if success then
return title
end
end
local function union(t1, t2)
-- Returns the union of two arrays.
local vals = {}
for i, v in ipairs(t1) do
vals[v] = true
end
for i, v in ipairs(t2) do
vals[v] = true
end
local ret = {}
for k in pairs(vals) do
table.insert(ret, k)
end
table.sort(ret)
return ret
end
local function getArgNums(args, prefix)
local nums = {}
for k, v in pairs(args) do
local num = mw.ustring.match(tostring(k), '^' .. prefix .. '([1-9]%d*)$')
if num then
table.insert(nums, tonumber(num))
end
end
table.sort(nums)
return nums
end
-- локальная обёртка, игнорирует таблицу с номерами дня, месяца и года
local function formatDate(txtDateIn, strFormat, params)
local txtDateOut, date, status = boxDate(txtDateIn, strFormat, params)
if status.brk then
return error(status.errorText)
else
return txtDateOut
end
end
--------------------------------------------------------------------------------
-- Box class definition
--------------------------------------------------------------------------------
local MessageBox = {}
MessageBox.__index = MessageBox
function MessageBox.new(boxType, args, cfg)
args = args or {}
local obj = {}
-- Set the title object and the namespace.
obj.title = getTitleObject(args.page) or mw.title.getCurrentTitle()
-- Set the config for our box type.
obj.cfg = cfg[boxType]
if not obj.cfg then
local ns = obj.title.namespace
-- boxType is "mbox" or invalid input
if ns == 0 then
obj.cfg = cfg.ambox -- main namespace
elseif ns == 6 then
obj.cfg = cfg.imbox -- file namespace
elseif ns == 14 then
obj.cfg = cfg.cmbox -- category namespace
else
local nsTable = mw.site.namespaces[ns]
if nsTable and nsTable.isTalk then
obj.cfg = cfg.tmbox -- any talk namespace
else
obj.cfg = cfg.ombox -- other namespaces or invalid input
end
end
end
-- Set the arguments, and remove all blank arguments except for the ones
-- listed in cfg.allowBlankParams.
do
local newArgs = {}
for k, v in pairs(args) do
if v ~= '' then
newArgs[k] = v
end
end
for i, param in ipairs(obj.cfg.allowBlankParams or {}) do
newArgs[param] = args[param]
end
obj.args = newArgs
end
-- Define internal data structure.
obj.categories = {}
obj.classes = {}
return setmetatable(obj, MessageBox)
end
function MessageBox:addCat(ns, cat, sort)
if not cat then
return nil
end
if sort then
cat = string.format('[[Категория:%s|%s]]', cat, sort)
else
cat = string.format('[[Категория:%s]]', cat)
end
self.categories[ns] = self.categories[ns] or {}
table.insert(self.categories[ns], cat)
end
function MessageBox:addClass(class)
if not class then
return nil
end
table.insert(self.classes, class)
end
function MessageBox:setParameters()
local args = self.args
local cfg = self.cfg
-- Get type data.
self.type = args.type
local typeData = cfg.types[self.type]
self.invalidTypeError = cfg.showInvalidTypeError
and self.type
and not typeData
typeData = typeData or cfg.types[cfg.default]
self.typeClass = typeData.class
self.typeImage = typeData.image
-- Find if the box has been wrongly substituted.
self.isSubstituted = cfg.substCheck and args.subst == 'SUBST'
-- Find whether we are using a small message box.
self.isSmall = cfg.allowSmall and (
cfg.smallParam and args.small == cfg.smallParam
or not cfg.smallParam and yesno(args.small)
)
-- Add attributes, classes and styles.
self.id = args.id
self.name = args.name
if self.name then
self:addClass('mbox-' .. string.gsub(self.name,' ','_'))
end
if yesno(args.plainlinks) ~= false then
self:addClass('plainlinks')
end
for _, class in ipairs(cfg.classes or {}) do
self:addClass(class)
end
if self.isSmall then
self:addClass(cfg.smallClass or 'mbox-small')
end
self:addClass(self.typeClass)
self:addClass(args.class)
self.style = args.style
self.attrs = args.attrs
self.dataLabel1 = args['data-label-1']
self.dataLabel2 = args['data-label-2']
self.dataLabel3 = args['data-label-3']
self.dataValue1 = args['data-value-1']
self.dataValue2 = args['data-value-2']
self.dataValue3 = args['data-value-3']
-- Set text style.
self.textstyle = args.textstyle
-- Find if we are on the template page or not. This functionality is only
-- used if useCollapsibleTextFields is set, or if both cfg.templateCategory
-- and cfg.templateCategoryRequireName are set.
self.useCollapsibleTextFields = cfg.useCollapsibleTextFields
if self.useCollapsibleTextFields
or cfg.templateCategory
and cfg.templateCategoryRequireName
then
self.name = args.name
if self.name then
local templateName = mw.ustring.match(
self.name,
'^[tT][eE][mM][pP][lL][aA][tT][eE][%s_]*:[%s_]*(.*)$'
) or self.name
templateName = ('Template:' .. templateName) or ('Шаблон:' .. templateName)
self.templateTitle = getTitleObject(templateName)
end
self.isTemplatePage = self.templateTitle
and mw.title.equals(self.title, self.templateTitle)
end
-- Process data for collapsible text fields. At the moment these are only
-- used in {{ambox}}.
if self.useCollapsibleTextFields then
-- Get the self.issue value.
if self.isSmall and args.smalltext then
self.issue = args.smalltext
else
if args.sect and args.sect ~= '' or nil then
local issue_sect = args.issue_sect
issue_sect = type(issue_sect) == 'string' and issue_sect ~= '' and issue_sect or nil
local text_sect = args.text_sect
text_sect = type(text_sect) == 'string' and text_sect ~= '' and text_sect or nil
local issues = {}
table.insert(issues, issue_sect)
table.insert(issues, text_sect)
self.issue = table.concat(issues, ' ')
else
local issue = args.issue
issue = type(issue) == 'string' and issue ~= '' and issue or nil
local text = args.text
text = type(text) == 'string' and text or nil
local issues = {}
table.insert(issues, issue)
table.insert(issues, text)
self.issue = table.concat(issues, ' ')
end
end
-- Get the self.talk value.
local talk = args.talk
-- Show talk links on the template page or template subpages if the talk
-- parameter is blank.
if talk == ''
and self.templateTitle
and (
mw.title.equals(self.templateTitle, self.title)
or self.title:isSubpageOf(self.templateTitle)
)
then
talk = '#'
elseif talk == '' then
talk = nil
end
if talk then
-- If the talk value is a talk page, make a link to that page. Else
-- assume that it's a section heading, and make a link to the talk
-- page of the current page with that section heading.
local talkTitle = getTitleObject(talk)
local talkArgIsTalkPage = true
if not talkTitle or not talkTitle.isTalkPage then
talkArgIsTalkPage = false
talkTitle = getTitleObject(
self.title.text,
mw.site.namespaces[self.title.namespace].talk.id
)
end
if talkTitle and talkTitle.exists then
local talkText = 'Соответствующую дискуссию можно найти на'
if talkArgIsTalkPage then
talkText = string.format(
'%s [[%s|%s]].',
talkText,
talk,
talkTitle.prefixedText
)
else
talkText = string.format(
'%s [[%s#%s|странице обсуждения]].',
talkText,
talkTitle.prefixedText,
talk
)
end
self.talk = talkText
end
end
-- Get other values.
self.fix = args.fix ~= '' and args.fix or nil
local date
if args.date and args.date ~= '' then
local status, result = pcall(formatDate, args.date)
if status then
date = string.format("(<span class='date'>%s</span>)", result)
else
date = string.format("<span class='error'>(Строка «%s» не является верной датой, пожалуйста, укажите дату в формате <code>ГГГГ-ММ-ДД</code>)</span>", args.date)
end
elseif args.date == '' and self.isTemplatePage then
date = string.format("(<span class='date'>%s</span>)", formatDate( lang:formatDate('Y-m-d') ) ) -- тут возникновения ошибки, связанной с пользовательским вводом, не будет
end
if date then
self.date = string.format(" <span class='mbox-date'>''%s''</span>", date)
end
self.info = args.info
if yesno(args.removalnotice) then
self.removalNotice = cfg.removalNotice
end
if args.shortFix then
self.shortFix = args.shortFix
end
end
-- Set the non-collapsible text field. At the moment this is used by all box
-- types other than ambox, and also by ambox when small=yes.
if self.isSmall then
self.text = args.smalltext or args.text
else
self.text = args.text
self.textsmall = args['text-small']
end
-- Set the below row.
self.below = cfg.below and args.below
-- General image settings.
self.imageCellDiv = not self.isSmall and cfg.imageCellDiv
self.imageEmptyCell = cfg.imageEmptyCell
if cfg.imageEmptyCellStyle then
self.imageEmptyCellStyle = 'border:none;padding:0px;width:1px'
end
-- Left image settings.
local imageLeft = self.isSmall and args.smallimage or args.image
if cfg.imageCheckBlank and imageLeft ~= 'blank' and imageLeft ~= 'none' and imageLeft ~= ''
or not cfg.imageCheckBlank and imageLeft ~= 'none'
then
self.imageLeft = imageLeft
if not imageLeft then
local imageSize = self.isSmall
and (cfg.imageSmallSize or '30x30px')
or cfg.imageSize
or '40x40px'
self.imageLeft = string.format('[[File:%s|%s|alt=]]', self.typeImage
or 'Information icon4.svg', imageSize)
end
end
-- Right image settings.
local imageRight = self.isSmall and args.smallimageright or args.imageright
if not (cfg.imageRightNone and imageRight == 'none') then
self.imageRight = imageRight
end
-- set templatestyles
self.base_templatestyles = cfg.templatestyles
end
function MessageBox:setMainspaceCategories()
local args = self.args
local cfg = self.cfg
local date = nil
if not cfg.allowMainspaceCategories then
return nil
end
local nums = {}
for _, prefix in ipairs{'cat', 'category', 'all'} do
args[prefix .. '1'] = args[prefix]
nums = union(nums, getArgNums(args, prefix))
end
-- The following is roughly equivalent to the old {{Ambox/category}}.
local status, result = pcall(formatDate, args.date, 'xg Y')
if status then
date = result
end
date = type(date) == 'string' and date
local preposition = 'с'
local suffix = 'года'
for _, num in ipairs(nums) do
local mainCat = args['cat' .. tostring(num)]
or args['category' .. tostring(num)]
local allCat = args['all' .. tostring(num)]
mainCat = type(mainCat) == 'string' and mainCat
allCat = type(allCat) == 'string' and allCat
if mainCat and date and date ~= '' then
local catTitle = string.format('%s %s %s %s', mainCat, preposition, date, suffix)
self:addCat(0, catTitle)
catTitle = getTitleObject('Категория:' .. catTitle)
local status, result = pcall(formatDate, args.date)
if not status then
self:addCat(0, 'Википедия:Статьи с недопустимым параметром даты в шаблоне-сообщении')
end
elseif mainCat and (not date or date == '') then
self:addCat(0, mainCat)
end
if allCat then
self:addCat(0, allCat)
end
end
end
function MessageBox:setTemplateCategories()
local args = self.args
local cfg = self.cfg
-- Add template categories.
if cfg.templateCategory then
if cfg.templateCategoryRequireName then
if self.isTemplatePage then
self:addCat(10, cfg.templateCategory)
end
elseif not self.title.isSubpage then
self:addCat(10, cfg.templateCategory)
end
end
-- Add template error categories.
if cfg.templateErrorCategory then
local templateErrorCategory = cfg.templateErrorCategory
local templateCat, templateSort
if not self.name and not self.title.isSubpage then
templateCat = templateErrorCategory
elseif self.isTemplatePage then
local paramsToCheck = cfg.templateErrorParamsToCheck or {}
local count = 0
for i, param in ipairs(paramsToCheck) do
if not args[param] then
count = count + 1
end
end
if count > 0 then
templateCat = templateErrorCategory
templateSort = tostring(count)
end
if self.categoryNums and #self.categoryNums > 0 then
templateCat = templateErrorCategory
templateSort = 'C'
end
end
self:addCat(10, templateCat, templateSort)
end
end
function MessageBox:setAllNamespaceCategories()
-- Set categories for all namespaces.
if self.invalidTypeError then
local allSort = (self.title.namespace == 0 and 'Main:' or '') .. self.title.prefixedText
self:addCat('all', 'Википедия:Необходимо исправить параметр в шаблоне-сообщении', allSort)
end
if self.isSubstituted then
self:addCat('all', 'Википедия:Страницы с ошибочно подставленными шаблонами')
end
if self.isSmall then
self:addCat(0, 'Википедия:Страницы с малыми шаблонами-сообщениями')
end
end
function MessageBox:setCategories()
if self.title.namespace == 0 then
self:setMainspaceCategories()
elseif self.title.namespace == 10 then
self:setTemplateCategories()
end
self:setAllNamespaceCategories()
end
function MessageBox:renderCategories()
-- Convert category tables to strings and pass them through
-- [[Module:Category handler]].
return categoryHandler{
main = table.concat(self.categories[0] or {}),
template = table.concat(self.categories[10] or {}),
all = table.concat(self.categories.all or {}),
nocat = self.args.nocat,
page = self.args.page
}
end
function MessageBox:export()
local root = mw.html.create()
-- Add the subst check error.
if self.isSubstituted and self.name then
root:tag('b')
:addClass('error')
:wikitext(string.format(
'Шаблон <code>%s[[Шаблон:%s|%s]]%s</code> был неккоректно подставлен.',
mw.text.nowiki('{{'), self.name, self.name, mw.text.nowiki('}}')
))
end
-- Conditional TemplateStyles loading
if self.base_templatestyles then
local frame = mw.getCurrentFrame()
root:wikitext(frame:extensionTag{
name = 'templatestyles',
args = { src = self.base_templatestyles },
})
end
-- Create the box table.
local boxTable = root:tag('table')
boxTable:attr('id', self.id or nil)
for i, class in ipairs(self.classes or {}) do
boxTable:addClass(class or nil)
end
boxTable
:cssText(self.style or nil)
:attr('role', 'presentation')
if self.dataLabel1 then
boxTable:attr('data-' .. self.dataLabel1, self.dataValue1)
end
if self.dataLabel2 then
boxTable:attr('data-' .. self.dataLabel2, self.dataValue2)
end
if self.dataLabel3 then
boxTable:attr('data-' .. self.dataLabel3, self.dataValue3)
end
if self.attrs then
boxTable:attr(self.attrs)
end
-- Add the left-hand image.
local row = boxTable:tag('tr')
if self.imageLeft then
local imageLeftCell = row:tag('td'):addClass('mbox-image')
if self.imageCellDiv then
-- If we are using a div, redefine imageLeftCell so that the image
-- is inside it. Divs use style="width: 52px;", which limits the
-- image width to 52px. If any images in a div are wider than that,
-- they may overlap with the text or cause other display problems.
imageLeftCell = imageLeftCell:tag('div'):css('width', '52px')
end
imageLeftCell:wikitext(self.imageLeft or nil)
elseif self.imageEmptyCell then
-- Some message boxes define an empty cell if no image is specified, and
-- some don't. The old template code in templates where empty cells are
-- specified gives the following hint: "No image. Cell with some width
-- or padding necessary for text cell to have 100% width."
row:tag('td')
:addClass('mbox-empty-cell')
:cssText(self.imageEmptyCellStyle or nil)
end
-- Add the text.
local textCell = row:tag('td'):addClass('mbox-text')
if self.useCollapsibleTextFields then
-- The message box uses advanced text parameters that allow things to be
-- collapsible. At the moment, only ambox uses this.
textCell:cssText(self.textstyle or nil)
local textCellDiv = textCell:tag('div')
textCellDiv
:addClass('mbox-text-div')
:wikitext(self.issue or nil)
local textsmallCellDiv = textCell:tag('div')
textsmallCellDiv
:addClass('mbox-textsmall-div hide-when-compact')
:cssText(self.textsmallstyle)
:wikitext(self.textsmall or nil)
if (self.talk or self.fix) and not self.isSmall then
textsmallCellDiv:tag('span')
:addClass('hide-when-compact')
:wikitext(self.fix and (' ' .. self.fix) or nil)
:wikitext(self.talk and (' ' .. self.talk) or nil)
end
if self.textsmall or self.fix or self.talk then
textsmallCellDiv:wikitext(self.date and (' ' .. self.date) or nil)
else
textCellDiv:wikitext(self.date and (' ' .. self.date) or nil)
end
if self.info and not self.isSmall then
textsmallCellDiv
:tag('span')
:addClass('hide-when-compact')
:wikitext(self.info and (' ' .. self.info) or nil)
end
if self.removalNotice then
textsmallCellDiv:tag('small')
:addClass('hide-when-compact')
:tag('i')
:wikitext(string.format(" (%s)", self.removalNotice))
end
if self.shortFix then
textCell:tag('div')
:addClass('mbox-multiply')
:tag('span')
:wikitext(string.format("%s", self.shortFix))
:tag('span')
:wikitext(self.date and (' ' .. self.date) or nil)
end
else
-- Default text formatting - anything goes.
textCell
:cssText(self.textstyle or nil)
:wikitext(self.text or nil)
end
-- Add the right-hand image.
if self.imageRight then
local imageRightCell = row:tag('td'):addClass('mbox-imageright')
if self.imageCellDiv then
-- If we are using a div, redefine imageRightCell so that the image
-- is inside it.
imageRightCell = imageRightCell:tag('div'):css('width', '52px')
end
imageRightCell
:wikitext(self.imageRight or nil)
end
-- Add the below row.
if self.below then
boxTable:tag('tr')
:tag('td')
:attr('colspan', self.imageRight and '3' or '2')
:addClass('mbox-text')
:cssText(self.textstyle or nil)
:wikitext(self.below or nil)
end
-- Add error message for invalid type parameters.
if self.invalidTypeError then
root:tag('div')
:css('text-align', 'center')
:wikitext(string.format(
'Этот шаблон-сообщение использует неверный параметр "type=%s", необходимо исправить.',
self.type or ''
))
end
-- Add categories.
root:wikitext(self:renderCategories() or nil)
return tostring(root)
end
--------------------------------------------------------------------------------
-- Exports
--------------------------------------------------------------------------------
local p, mt = {}, {}
function p._exportClasses()
-- For testing.
return {
MessageBox = MessageBox
}
end
function p.main(boxType, args, cfgTables)
local box = MessageBox.new(boxType, args, cfgTables or mw.loadData(CONFIG_MODULE))
box:setParameters()
box:setCategories()
return box:export()
end
function mt.__index(t, k)
return function (frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
return t.main(k, getArgs(frame, {trim = false, removeBlanks = false}))
end
end
return setmetatable(p, mt)
f2539b657a9cdadde7c0dd5ad270d3095b2bdd54
660
624
2024-08-16T16:41:09Z
DuOfOrl
5
Scribunto
text/plain
-- This is a meta-module for producing message box templates, including
-- {{mbox}}, {{ambox}}, {{imbox}}, {{tmbox}}, {{ombox}}, {{cmbox}} and {{fmbox}}.
-- Load necessary modules.
require('Module:No globals')
local getArgs
local categoryHandler = require('Module:Category handler')._main
local yesno = require('Module:Yesno')
local boxDate = require('Module:Calendar').bxDate;
-- Get a language object for formatDate and ucfirst.
local lang = mw.language.getContentLanguage()
-- Define constants
local CONFIG_MODULE = 'Module:Message box/configuration'
--------------------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------------------
local function getTitleObject(...)
-- Get the title object, passing the function through pcall
-- in case we are over the expensive function count limit.
local success, title = pcall(mw.title.new, ...)
if success then
return title
end
end
local function union(t1, t2)
-- Returns the union of two arrays.
local vals = {}
for i, v in ipairs(t1) do
vals[v] = true
end
for i, v in ipairs(t2) do
vals[v] = true
end
local ret = {}
for k in pairs(vals) do
table.insert(ret, k)
end
table.sort(ret)
return ret
end
local function getArgNums(args, prefix)
local nums = {}
for k, v in pairs(args) do
local num = mw.ustring.match(tostring(k), '^' .. prefix .. '([1-9]%d*)$')
if num then
table.insert(nums, tonumber(num))
end
end
table.sort(nums)
return nums
end
-- локальная обёртка, игнорирует таблицу с номерами дня, месяца и года
local function formatDate(txtDateIn, strFormat, params)
local txtDateOut, date, status = boxDate(txtDateIn, strFormat, params)
if status.brk then
return error(status.errorText)
else
return txtDateOut
end
end
--------------------------------------------------------------------------------
-- Box class definition
--------------------------------------------------------------------------------
local MessageBox = {}
MessageBox.__index = MessageBox
function MessageBox.new(boxType, args, cfg)
args = args or {}
local obj = {}
-- Set the title object and the namespace.
obj.title = getTitleObject(args.page) or mw.title.getCurrentTitle()
-- Set the config for our box type.
obj.cfg = cfg[boxType]
if not obj.cfg then
local ns = obj.title.namespace
-- boxType is "mbox" or invalid input
if ns == 0 then
obj.cfg = cfg.ambox -- main namespace
elseif ns == 6 then
obj.cfg = cfg.imbox -- file namespace
elseif ns == 14 then
obj.cfg = cfg.cmbox -- category namespace
else
local nsTable = mw.site.namespaces[ns]
if nsTable and nsTable.isTalk then
obj.cfg = cfg.tmbox -- any talk namespace
else
obj.cfg = cfg.ombox -- other namespaces or invalid input
end
end
end
-- Set the arguments, and remove all blank arguments except for the ones
-- listed in cfg.allowBlankParams.
do
local newArgs = {}
for k, v in pairs(args) do
if v ~= '' then
newArgs[k] = v
end
end
for i, param in ipairs(obj.cfg.allowBlankParams or {}) do
newArgs[param] = args[param]
end
obj.args = newArgs
end
-- Define internal data structure.
obj.categories = {}
obj.classes = {}
return setmetatable(obj, MessageBox)
end
function MessageBox:addCat(ns, cat, sort)
if not cat then
return nil
end
if sort then
cat = string.format('[[Категория:%s|%s]]', cat, sort)
else
cat = string.format('[[Категория:%s]]', cat)
end
self.categories[ns] = self.categories[ns] or {}
table.insert(self.categories[ns], cat)
end
function MessageBox:addClass(class)
if not class then
return nil
end
table.insert(self.classes, class)
end
function MessageBox:setParameters()
local args = self.args
local cfg = self.cfg
-- Get type data.
self.type = args.type
local typeData = cfg.types[self.type]
self.invalidTypeError = cfg.showInvalidTypeError
and self.type
and not typeData
typeData = typeData or cfg.types[cfg.default]
self.typeClass = typeData.class
self.typeImage = typeData.image
-- Find if the box has been wrongly substituted.
self.isSubstituted = cfg.substCheck and args.subst == 'SUBST'
-- Find whether we are using a small message box.
self.isSmall = cfg.allowSmall and (
cfg.smallParam and args.small == cfg.smallParam
or not cfg.smallParam and yesno(args.small)
)
-- Add attributes, classes and styles.
self.id = args.id
if yesno(args.plainlinks) ~= false then
self:addClass('plainlinks')
end
if args.mini then
self:addClass('ambox-mini')
end
for _, class in ipairs(cfg.classes or {}) do
self:addClass(class)
end
if self.isSmall then
self:addClass(cfg.smallClass or 'mbox-small')
end
self:addClass(self.typeClass)
self:addClass(args.class)
self.style = args.style
self.attrs = args.attrs
self.dataLabel1 = args['data-label-1']
self.dataLabel2 = args['data-label-2']
self.dataLabel3 = args['data-label-3']
self.dataValue1 = args['data-value-1']
self.dataValue2 = args['data-value-2']
self.dataValue3 = args['data-value-3']
-- Set text style.
self.textstyle = args.textstyle
-- Find if we are on the template page or not. This functionality is only
-- used if useCollapsibleTextFields is set, or if both cfg.templateCategory
-- and cfg.templateCategoryRequireName are set.
self.useCollapsibleTextFields = cfg.useCollapsibleTextFields
if self.useCollapsibleTextFields
or cfg.templateCategory
and cfg.templateCategoryRequireName
then
self.name = args.name
if self.name then
local templateName = mw.ustring.match(
self.name,
'^[tT][eE][mM][pP][lL][aA][tT][eE][%s_]*:[%s_]*(.*)$'
) or self.name
templateName = ('Template:' .. templateName) or ('Шаблон:' .. templateName)
self.templateTitle = getTitleObject(templateName)
end
self.isTemplatePage = self.templateTitle
and mw.title.equals(self.title, self.templateTitle)
end
-- Process data for collapsible text fields. At the moment these are only
-- used in {{ambox}}.
if self.useCollapsibleTextFields then
-- Get the self.issue value.
if self.isSmall and args.smalltext then
self.issue = args.smalltext
else
local sect
if args.sect == '' then
sect = '<span style="font-weight:bold">Эта ' .. (cfg.sectionDefault or 'статья') .. '</span>'
elseif type(args.sect) == 'string' then
sect = '<span style="font-weight:bold">' .. args.sect .. '</span>'
end
local issue = args.issue
issue = type(issue) == 'string' and issue ~= '' and issue or nil
local text = args.text
text = type(text) == 'string' and text or nil
local issues = {}
table.insert(issues, sect)
table.insert(issues, issue)
table.insert(issues, text)
self.issue = table.concat(issues, ' ')
end
-- Get the self.talk value.
local talk = args.talk
-- Show talk links on the template page or template subpages if the talk
-- parameter is blank.
if talk == ''
and self.templateTitle
and (
mw.title.equals(self.templateTitle, self.title)
or self.title:isSubpageOf(self.templateTitle)
)
then
talk = '#'
elseif talk == '' then
talk = nil
end
if talk then
-- If the talk value is a talk page, make a link to that page. Else
-- assume that it's a section heading, and make a link to the talk
-- page of the current page with that section heading.
local talkTitle = getTitleObject(talk)
local talkArgIsTalkPage = true
if not talkTitle or not talkTitle.isTalkPage then
talkArgIsTalkPage = false
talkTitle = getTitleObject(
self.title.text,
mw.site.namespaces[self.title.namespace].talk.id
)
end
if talkTitle and talkTitle.exists then
local talkText = 'Соответствующую дискуссию можно найти на'
if talkArgIsTalkPage then
talkText = string.format(
'%s [[%s|%s]].',
talkText,
talk,
talkTitle.prefixedText
)
else
talkText = string.format(
'%s [[%s#%s|странице обсуждения]].',
talkText,
talkTitle.prefixedText,
talk
)
end
self.talk = talkText
end
end
-- Get other values.
self.fix = args.fix ~= '' and args.fix or nil
local date
if args.date and args.date ~= '' then
local status, result = pcall(formatDate, args.date)
if status then
date = string.format("(<span class='date'>%s</span>)", result)
else
date = string.format("<span class='error'>(Строка «%s» не является верной датой, пожалуйста, укажите дату в формате <code>ГГГГ-ММ-ДД</code>)</span>", args.date)
end
elseif args.date == '' and self.isTemplatePage then
date = string.format("(<span class='date'>%s</span>)", formatDate( lang:formatDate('Y-m-d') ) ) -- тут возникновения ошибки, связанной с пользовательским вводом, не будет
end
if date then
self.date = string.format(" <span class='mbox-date'>''%s''</span>", date)
end
self.info = args.info
if yesno(args.removalnotice) then
self.removalNotice = cfg.removalNotice
end
if args.shortFix then
self.shortFix = args.shortFix
end
end
-- Set the non-collapsible text field. At the moment this is used by all box
-- types other than ambox, and also by ambox when small=yes.
if self.isSmall then
self.text = args.smalltext or args.text
else
self.text = args.text
self.textsmall = args['text-small']
end
-- Set the below row.
self.below = cfg.below and args.below
-- General image settings.
self.imageCellDiv = not self.isSmall and cfg.imageCellDiv
self.imageEmptyCell = cfg.imageEmptyCell
if cfg.imageEmptyCellStyle then
self.imageEmptyCellStyle = 'border:none;padding:0px;width:1px'
end
-- Left image settings.
local imageLeft = self.isSmall and args.smallimage or args.image
if cfg.imageCheckBlank and imageLeft ~= 'blank' and imageLeft ~= 'none' and imageLeft ~= ''
or not cfg.imageCheckBlank and imageLeft ~= 'none'
then
self.imageLeft = imageLeft
if not imageLeft then
local imageSize = self.isSmall
and (cfg.imageSmallSize or '30x30px')
or cfg.imageSize
or '40x40px'
self.imageLeft = string.format('[[File:%s|%s|alt=]]', self.typeImage
or 'Information icon4.svg', imageSize)
end
end
-- Right image settings.
local imageRight = self.isSmall and args.smallimageright or args.imageright
if not (cfg.imageRightNone and imageRight == 'none') then
self.imageRight = imageRight
end
end
function MessageBox:setMainspaceCategories()
local args = self.args
local cfg = self.cfg
local date = nil
if not cfg.allowMainspaceCategories then
return nil
end
local nums = {}
for _, prefix in ipairs{'cat', 'category', 'all'} do
args[prefix .. '1'] = args[prefix]
nums = union(nums, getArgNums(args, prefix))
end
-- The following is roughly equivalent to the old {{Ambox/category}}.
local status, result = pcall(formatDate, args.date, 'xg Y')
if status then
date = result
end
date = type(date) == 'string' and date
local preposition = 'с'
local suffix = 'года'
for _, num in ipairs(nums) do
local mainCat = args['cat' .. tostring(num)]
or args['category' .. tostring(num)]
local allCat = args['all' .. tostring(num)]
mainCat = type(mainCat) == 'string' and mainCat
allCat = type(allCat) == 'string' and allCat
if mainCat and date and date ~= '' then
local catTitle = string.format('%s %s %s %s', mainCat, preposition, date, suffix)
self:addCat(0, catTitle)
catTitle = getTitleObject('Категория:' .. catTitle)
local status, result = pcall(formatDate, args.date)
if not status then
self:addCat(0, 'Википедия:Статьи с недопустимым параметром даты в шаблоне-сообщении')
end
elseif mainCat and (not date or date == '') then
self:addCat(0, mainCat)
end
if allCat then
self:addCat(0, allCat)
end
end
end
function MessageBox:setTemplateCategories()
local args = self.args
local cfg = self.cfg
-- Add template categories.
if cfg.templateCategory then
if cfg.templateCategoryRequireName then
if self.isTemplatePage then
self:addCat(10, cfg.templateCategory)
end
elseif not self.title.isSubpage then
self:addCat(10, cfg.templateCategory)
end
end
-- Add template error categories.
if cfg.templateErrorCategory then
local templateErrorCategory = cfg.templateErrorCategory
local templateCat, templateSort
if not self.name and not self.title.isSubpage then
templateCat = templateErrorCategory
elseif self.isTemplatePage then
local paramsToCheck = cfg.templateErrorParamsToCheck or {}
local count = 0
for i, param in ipairs(paramsToCheck) do
if not args[param] then
count = count + 1
end
end
if count > 0 then
templateCat = templateErrorCategory
templateSort = tostring(count)
end
if self.categoryNums and #self.categoryNums > 0 then
templateCat = templateErrorCategory
templateSort = 'C'
end
end
self:addCat(10, templateCat, templateSort)
end
end
function MessageBox:setAllNamespaceCategories()
-- Set categories for all namespaces.
if self.invalidTypeError then
local allSort = (self.title.namespace == 0 and 'Main:' or '') .. self.title.prefixedText
self:addCat('all', 'Википедия:Необходимо исправить параметр в шаблоне-сообщении', allSort)
end
if self.isSubstituted then
self:addCat('all', 'Википедия:Страницы с ошибочно подставленными шаблонами')
end
end
function MessageBox:setCategories()
if self.title.namespace == 0 then
self:setMainspaceCategories()
elseif self.title.namespace == 10 then
self:setTemplateCategories()
end
self:setAllNamespaceCategories()
end
function MessageBox:renderCategories()
-- Convert category tables to strings and pass them through
-- [[Module:Category handler]].
return categoryHandler{
main = table.concat(self.categories[0] or {}),
template = table.concat(self.categories[10] or {}),
all = table.concat(self.categories.all or {}),
nocat = self.args.nocat,
page = self.args.page
}
end
function MessageBox:export()
local root = mw.html.create()
-- Add the subst check error.
if self.isSubstituted and self.name then
root:tag('b')
:addClass('error')
:wikitext(string.format(
'Шаблон <code>%s[[Шаблон:%s|%s]]%s</code> был неккоректно подставлен.',
mw.text.nowiki('{{'), self.name, self.name, mw.text.nowiki('}}')
))
end
-- Create the box table.
local boxTable = root:tag('table')
boxTable:attr('id', self.id or nil)
for i, class in ipairs(self.classes or {}) do
boxTable:addClass(class or nil)
end
boxTable
:cssText(self.style or nil)
:attr('role', 'presentation')
if self.dataLabel1 then
boxTable:attr('data-' .. self.dataLabel1, self.dataValue1)
end
if self.dataLabel2 then
boxTable:attr('data-' .. self.dataLabel2, self.dataValue2)
end
if self.dataLabel3 then
boxTable:attr('data-' .. self.dataLabel3, self.dataValue3)
end
if self.attrs then
boxTable:attr(self.attrs)
end
-- Add the left-hand image.
local row = boxTable:tag('tr')
if self.imageLeft then
local imageLeftCell = row:tag('td'):addClass('mbox-image')
if self.imageCellDiv then
-- If we are using a div, redefine imageLeftCell so that the image
-- is inside it. Divs use style="width: 52px;", which limits the
-- image width to 52px. If any images in a div are wider than that,
-- they may overlap with the text or cause other display problems.
imageLeftCell = imageLeftCell:tag('div'):css('width', '52px')
end
imageLeftCell:wikitext(self.imageLeft or nil)
elseif self.imageEmptyCell then
-- Some message boxes define an empty cell if no image is specified, and
-- some don't. The old template code in templates where empty cells are
-- specified gives the following hint: "No image. Cell with some width
-- or padding necessary for text cell to have 100% width."
row:tag('td')
:addClass('mbox-empty-cell')
:cssText(self.imageEmptyCellStyle or nil)
end
-- Add the text.
local textCell = row:tag('td'):addClass('mbox-text')
if self.useCollapsibleTextFields then
-- The message box uses advanced text parameters that allow things to be
-- collapsible. At the moment, only ambox uses this.
textCell:cssText(self.textstyle or nil)
local textCellDiv = textCell:tag('div')
textCellDiv
:addClass('mbox-text-div')
:wikitext(self.issue or nil)
local textsmallCellDiv = textCell:tag('div')
textsmallCellDiv
:addClass('mbox-textsmall-div hide-when-compact')
:cssText(self.textsmallstyle or 'font-size:85%')
:wikitext(self.textsmall or nil)
if (self.talk or self.fix) and not self.isSmall then
textsmallCellDiv:tag('span')
:addClass('hide-when-compact')
:wikitext(self.talk and (' ' .. self.talk) or nil)
:wikitext(self.fix and (' ' .. self.fix) or nil)
end
textsmallCellDiv:wikitext(self.date and (' ' .. self.date) or nil)
if self.info and not self.isSmall then
textsmallCellDiv
:tag('span')
:addClass('hide-when-compact')
:wikitext(self.info and (' ' .. self.info) or nil)
end
if self.removalNotice then
textsmallCellDiv:tag('small')
:addClass('hide-when-compact')
:tag('i')
:wikitext(string.format(" (%s)", self.removalNotice))
end
if self.shortFix then
textCell:tag('div')
:addClass('mbox-multiply')
:tag('span')
:wikitext(string.format("%s", self.shortFix))
:tag('span')
:wikitext(self.date and (' ' .. self.date) or nil)
end
else
-- Default text formatting - anything goes.
textCell
:cssText(self.textstyle or nil)
:wikitext(self.text or nil)
end
-- Add the right-hand image.
if self.imageRight then
local imageRightCell = row:tag('td'):addClass('mbox-imageright')
if self.imageCellDiv then
-- If we are using a div, redefine imageRightCell so that the image
-- is inside it.
imageRightCell = imageRightCell:tag('div'):css('width', '52px')
end
imageRightCell
:wikitext(self.imageRight or nil)
end
-- Add the below row.
if self.below then
boxTable:tag('tr')
:tag('td')
:attr('colspan', self.imageRight and '3' or '2')
:addClass('mbox-text')
:cssText(self.textstyle or nil)
:wikitext(self.below or nil)
end
-- Add error message for invalid type parameters.
if self.invalidTypeError then
root:tag('div')
:css('text-align', 'center')
:wikitext(string.format(
'Этот шаблон-сообщение использует неверный параметр "type=%s", необходимо исправить.',
self.type or ''
))
end
-- Add categories.
root:wikitext(self:renderCategories() or nil)
return tostring(root)
end
--------------------------------------------------------------------------------
-- Exports
--------------------------------------------------------------------------------
local p, mt = {}, {}
function p._exportClasses()
-- For testing.
return {
MessageBox = MessageBox
}
end
function p.main(boxType, args, cfgTables)
local box = MessageBox.new(boxType, args, cfgTables or mw.loadData(CONFIG_MODULE))
box:setParameters()
box:setCategories()
return box:export()
end
function mt.__index(t, k)
return function (frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
return t.main(k, getArgs(frame, {trim = false, removeBlanks = false}))
end
end
return setmetatable(p, mt)
f7438b70acb7f9253502968228af5c073b3b1ca5
Модуль:Message box/configuration
828
67
626
107
2024-08-16T16:22:40Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Message box configuration --
-- --
-- This module contains configuration data for [[Module:Message box]]. --
--------------------------------------------------------------------------------
return {
ambox = {
types = {
speedy = {
class = 'ambox-speedy',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'ambox-delete',
image = 'Stop hand nuvola.svg'
},
content = {
class = 'ambox-content',
image = 'Emblem-important.svg'
},
style = {
class = 'ambox-style',
image = 'Broom_icon.svg'
},
move = {
class = 'ambox-move',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'ambox-protection',
image = 'Padlock-silver-medium.svg'
},
notice = {
class = 'ambox-notice',
image = 'Information.svg'
},
good = {
class = 'ambox-good',
image = 'Green star boxed.svg'
},
serious = {
class = 'ambox-serious',
image = 'Stop hand nuvola.svg'
},
merge = {
class = 'ambox-merge',
image = 'Merge-split-transwiki default.svg'
},
discussion = {
class = 'ambox-discussion',
image = 'Nuvola apps ksirc.png'
}
},
default = 'notice',
allowBlankParams = {'talk', 'sect', 'date', 'issue', 'fix', 'subst', 'hidden', 'image'},
allowSmall = true,
smallParam = 'left',
smallClass = 'mbox-small-left',
substCheck = true,
classes = {'metadata', 'ambox'},
imageEmptyCell = true,
imageCheckBlank = true,
imageSmallSize = '20x20px',
imageCellDiv = true,
useCollapsibleTextFields = true,
imageRightNone = true,
sectionDefault = 'статья',
allowMainspaceCategories = true,
templateCategory = 'Шаблоны:Шаблоны-сообщения для статей',
templateCategoryRequireName = true,
templateErrorCategory = 'Шаблоны:Шаблоны-сообщения для статей с пропущенными параметрами',
templateErrorParamsToCheck = {'issue', 'fix'},
removalNotice = '[[Help:Maintenance template removal|Learn how and when to remove this template message]]',
templatestyles = 'Module:Message box/ambox.css',
},
cmbox = {
types = {
speedy = {
class = 'cmbox-speedy notheme',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'cmbox-delete notheme',
image = 'Ambox warning pn.svg'
},
content = {
class = 'cmbox-content notheme',
image = 'Ambox important.svg'
},
style = {
class = 'cmbox-style notheme',
image = 'Edit-clear.svg'
},
move = {
class = 'cmbox-move notheme',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'cmbox-protection notheme',
image = 'Padlock-silver-medium.svg'
},
notice = {
class = 'cmbox-notice notheme',
image = 'Information icon4.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'cmbox'},
imageEmptyCell = true,
useCollapsibleTextFields = true,
templatestyles = 'Module:Message box/cmbox.css',
},
fmbox = {
types = {
warning = {
class = 'fmbox-warning',
image = 'Ambox warning pn.svg'
},
editnotice = {
class = 'fmbox-editnotice',
image = 'Information icon4.svg'
},
system = {
class = 'fmbox-system',
image = 'Information icon4.svg'
}
},
default = 'system',
showInvalidTypeError = true,
classes = {'fmbox'},
imageEmptyCell = false,
imageRightNone = false,
useCollapsibleTextFields = true,
templatestyles = 'Module:Message box/fmbox.css',
},
imbox = {
types = {
speedy = {
class = 'imbox-speedy',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'imbox-delete',
image = 'Ambox warning pn.svg'
},
content = {
class = 'imbox-content',
image = 'Ambox important.svg'
},
style = {
class = 'imbox-style',
image = 'Edit-clear.svg'
},
move = {
class = 'imbox-move',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'imbox-protection',
image = 'Padlock-silver-medium.svg'
},
license = {
class = 'imbox-license licensetpl',
image = 'Imbox license.png' -- @todo We need an SVG version of this
},
featured = {
class = 'imbox-featured',
image = 'Cscr-featured.svg'
},
notice = {
class = 'imbox-notice',
image = 'Information icon4.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'imbox'},
imageEmptyCell = true,
below = true,
useCollapsibleTextFields = true,
templateCategory = 'Шаблоны:Шаблоны-сообщения для файлов',
templatestyles = 'Module:Message box/imbox.css',
},
ombox = {
types = {
speedy = {
class = 'ombox-speedy',
image = 'OOjs UI icon alert-destructive.svg'
},
delete = {
class = 'ombox-delete',
image = 'OOjs UI icon alert-destructive.svg'
},
content = {
class = 'ombox-content',
image = 'OOjs UI icon notice-warning.svg'
},
style = {
class = 'ombox-style',
image = 'Edit-clear.svg'
},
move = {
class = 'ombox-move',
image = 'Imbox move.png'
},
protection = {
class = 'ombox-protection',
image = 'Imbox protection.png'
},
notice = {
class = 'ombox-notice',
image = 'OOjs UI icon info-progressive.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'ombox'},
allowSmall = true,
imageEmptyCell = true,
imageRightNone = true,
useCollapsibleTextFields = true,
templatestyles = 'Module:Message box/ombox.css',
},
tmbox = {
types = {
speedy = {
class = 'tmbox-speedy notheme',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'tmbox-delete notheme',
image = 'Ambox warning pn.svg'
},
content = {
class = 'tmbox-content notheme',
image = 'Ambox important.svg'
},
style = {
class = 'tmbox-style notheme',
image = 'Edit-clear.svg'
},
move = {
class = 'tmbox-move notheme',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'tmbox-protection notheme',
image = 'Padlock-silver-medium.svg'
},
notice = {
class = 'tmbox-notice notheme',
image = 'Information icon4.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'tmbox'},
allowSmall = true,
imageRightNone = true,
imageEmptyCell = true,
imageEmptyCellStyle = true,
useCollapsibleTextFields = true,
templateCategory = 'Шаблоны:Шаблоны-сообщения для страниц обсуждений',
templatestyles = 'Module:Message box/tmbox.css',
}
}
dd71cfc9b05d5244df926bfe86dfdb7ad0e0ff85
661
626
2024-08-16T16:43:22Z
DuOfOrl
5
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Message box configuration --
-- --
-- This module contains configuration data for [[Module:Message box]]. --
--------------------------------------------------------------------------------
return {
ambox = {
types = {
speedy = {
class = 'ambox-speedy',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'ambox-delete',
image = 'Stop hand nuvola.svg'
},
content = {
class = 'ambox-content',
image = 'Emblem-important.svg'
},
style = {
class = 'ambox-style',
image = 'Broom_icon.svg'
},
move = {
class = 'ambox-move',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'ambox-protection',
image = 'Padlock-silver-medium.svg'
},
notice = {
class = 'ambox-notice',
image = 'Information.svg'
},
good = {
class = 'ambox-good',
image = 'Green star boxed.svg'
},
serious = {
class = 'ambox-serious',
image = 'Stop hand nuvola.svg'
},
merge = {
class = 'ambox-merge',
image = 'Merge-split-transwiki default.svg'
},
discussion = {
class = 'ambox-discussion',
image = 'Nuvola apps ksirc.png'
}
},
default = 'notice',
allowBlankParams = {'talk', 'sect', 'date', 'issue', 'fix', 'subst', 'hidden', 'image'},
allowSmall = true,
smallParam = 'left',
smallClass = 'mbox-small-left',
substCheck = true,
classes = {'metadata', 'ambox'},
imageEmptyCell = true,
imageCheckBlank = true,
imageSmallSize = '20x20px',
imageCellDiv = true,
useCollapsibleTextFields = true,
imageRightNone = true,
sectionDefault = 'статья',
allowMainspaceCategories = true,
templateCategory = 'Шаблоны:Шаблоны-сообщения для статей',
templateCategoryRequireName = true,
templateErrorCategory = 'Шаблоны:Шаблоны-сообщения для статей с пропущенными параметрами',
templateErrorParamsToCheck = {'issue', 'fix'},
removalNotice = '[[Help:Maintenance template removal|Learn how and when to remove this template message]]'
},
cmbox = {
types = {
speedy = {
class = 'cmbox-speedy',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'cmbox-delete',
image = 'Ambox warning pn.svg'
},
content = {
class = 'cmbox-content',
image = 'Ambox important.svg'
},
style = {
class = 'cmbox-style',
image = 'Edit-clear.svg'
},
move = {
class = 'cmbox-move',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'cmbox-protection',
image = 'Padlock-silver-medium.svg'
},
notice = {
class = 'cmbox-notice',
image = 'Information icon4.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'cmbox'},
imageEmptyCell = true,
useCollapsibleTextFields = true
},
fmbox = {
types = {
warning = {
class = 'fmbox-warning',
image = 'Ambox warning pn.svg'
},
editnotice = {
class = 'fmbox-editnotice',
image = 'Information icon4.svg'
},
system = {
class = 'fmbox-system',
image = 'Information icon4.svg'
}
},
default = 'system',
showInvalidTypeError = true,
classes = {'fmbox'},
imageEmptyCell = false,
imageRightNone = false,
useCollapsibleTextFields = true
},
imbox = {
types = {
speedy = {
class = 'imbox-speedy',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'imbox-delete',
image = 'Ambox warning pn.svg'
},
content = {
class = 'imbox-content',
image = 'Ambox important.svg'
},
style = {
class = 'imbox-style',
image = 'Edit-clear.svg'
},
move = {
class = 'imbox-move',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'imbox-protection',
image = 'Padlock-silver-medium.svg'
},
license = {
class = 'imbox-license licensetpl',
image = 'Imbox license.png' -- @todo We need an SVG version of this
},
featured = {
class = 'imbox-featured',
image = 'Cscr-featured.svg'
},
notice = {
class = 'imbox-notice',
image = 'Information icon4.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'imbox'},
imageEmptyCell = true,
below = true,
useCollapsibleTextFields = true,
templateCategory = 'Шаблоны:Шаблоны-сообщения для файлов'
},
ombox = {
types = {
speedy = {
class = 'ombox-speedy',
image = 'OOjs UI icon alert-destructive.svg'
},
delete = {
class = 'ombox-delete',
image = 'OOjs UI icon alert-destructive.svg'
},
content = {
class = 'ombox-content',
image = 'OOjs UI icon notice-warning.svg'
},
style = {
class = 'ombox-style',
image = 'Edit-clear.svg'
},
move = {
class = 'ombox-move',
image = 'Imbox move.png'
},
protection = {
class = 'ombox-protection',
image = 'Imbox protection.png'
},
notice = {
class = 'ombox-notice',
image = 'OOjs UI icon info-progressive.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'ombox'},
allowSmall = true,
imageEmptyCell = true,
imageRightNone = true,
useCollapsibleTextFields = true
},
tmbox = {
types = {
speedy = {
class = 'tmbox-speedy',
image = 'Ambox warning pn.svg'
},
delete = {
class = 'tmbox-delete',
image = 'Ambox warning pn.svg'
},
content = {
class = 'tmbox-content',
image = 'Ambox important.svg'
},
style = {
class = 'tmbox-style',
image = 'Edit-clear.svg'
},
move = {
class = 'tmbox-move',
image = 'Merge-split-transwiki default.svg'
},
protection = {
class = 'tmbox-protection',
image = 'Padlock-silver-medium.svg'
},
notice = {
class = 'tmbox-notice',
image = 'Information icon4.svg'
}
},
default = 'notice',
showInvalidTypeError = true,
classes = {'tmbox'},
allowSmall = true,
imageRightNone = true,
imageEmptyCell = true,
imageEmptyCellStyle = true,
useCollapsibleTextFields = true,
templateCategory = 'Шаблоны:Шаблоны-сообщения для страниц обсуждений'
}
}
569b6dcbf9ec9858c77ddf8aefe198cd3f90a950
Модуль:Namespace detect/config
828
77
628
127
2024-08-16T16:22:40Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Namespace detect configuration data --
-- --
-- This module stores configuration data for Module:Namespace detect. Here --
-- you can localise the module to your wiki's language. --
-- --
-- To activate a configuration item, you need to uncomment it. This means --
-- that you need to remove the text "-- " at the start of the line. --
--------------------------------------------------------------------------------
local cfg = {} -- Don't edit this line.
--------------------------------------------------------------------------------
-- Parameter names --
-- These configuration items specify custom parameter names. Values added --
-- here will work in addition to the default English parameter names. --
-- To add one extra name, you can use this format: --
-- --
-- cfg.foo = 'parameter name' --
-- --
-- To add multiple names, you can use this format: --
-- --
-- cfg.foo = {'parameter name 1', 'parameter name 2', 'parameter name 3'} --
--------------------------------------------------------------------------------
---- This parameter displays content for the main namespace:
-- cfg.main = 'main'
---- This parameter displays in talk namespaces:
-- cfg.talk = 'talk'
---- This parameter displays content for "other" namespaces (namespaces for which
---- parameters have not been specified):
-- cfg.other = 'other'
---- This parameter makes talk pages behave as though they are the corresponding
---- subject namespace. Note that this parameter is used with [[Module:Yesno]].
---- Edit that module to change the default values of "yes", "no", etc.
-- cfg.subjectns = 'subjectns'
---- This parameter sets a demonstration namespace:
-- cfg.demospace = 'demospace'
---- This parameter sets a specific page to compare:
cfg.demopage = 'page'
--------------------------------------------------------------------------------
-- Table configuration --
-- These configuration items allow customisation of the "table" function, --
-- used to generate a table of possible parameters in the module --
-- documentation. --
--------------------------------------------------------------------------------
---- The header for the namespace column in the wikitable containing the list of
---- possible subject-space parameters.
-- cfg.wikitableNamespaceHeader = 'Namespace'
---- The header for the wikitable containing the list of possible subject-space
---- parameters.
-- cfg.wikitableAliasesHeader = 'Aliases'
--------------------------------------------------------------------------------
-- End of configuration data --
--------------------------------------------------------------------------------
return cfg -- Don't edit this line.
0e4ff08d13c4b664d66b32c232deb129b77c1a56
Модуль:Namespace detect/data
828
76
630
125
2024-08-16T16:22:41Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
--------------------------------------------------------------------------------
-- Namespace detect data --
-- This module holds data for [[Module:Namespace detect]] to be loaded per --
-- page, rather than per #invoke, for performance reasons. --
--------------------------------------------------------------------------------
local cfg = require('Module:Namespace detect/config')
local function addKey(t, key, defaultKey)
if key ~= defaultKey then
t[#t + 1] = key
end
end
-- Get a table of parameters to query for each default parameter name.
-- This allows wikis to customise parameter names in the cfg table while
-- ensuring that default parameter names will always work. The cfg table
-- values can be added as a string, or as an array of strings.
local defaultKeys = {
'main',
'talk',
'other',
'subjectns',
'demospace',
'demopage'
}
local argKeys = {}
for i, defaultKey in ipairs(defaultKeys) do
argKeys[defaultKey] = {defaultKey}
end
for defaultKey, t in pairs(argKeys) do
local cfgValue = cfg[defaultKey]
local cfgValueType = type(cfgValue)
if cfgValueType == 'string' then
addKey(t, cfgValue, defaultKey)
elseif cfgValueType == 'table' then
for i, key in ipairs(cfgValue) do
addKey(t, key, defaultKey)
end
end
cfg[defaultKey] = nil -- Free the cfg value as we don't need it any more.
end
local function getParamMappings()
--[[
-- Returns a table of how parameter names map to namespace names. The keys
-- are the actual namespace names, in lower case, and the values are the
-- possible parameter names for that namespace, also in lower case. The
-- table entries are structured like this:
-- {
-- [''] = {'main'},
-- ['wikipedia'] = {'wikipedia', 'project', 'wp'},
-- ...
-- }
--]]
local mappings = {}
local mainNsName = mw.site.subjectNamespaces[0].name
mainNsName = mw.ustring.lower(mainNsName)
mappings[mainNsName] = mw.clone(argKeys.main)
mappings['talk'] = mw.clone(argKeys.talk)
for nsid, ns in pairs(mw.site.subjectNamespaces) do
if nsid ~= 0 then -- Exclude main namespace.
local nsname = mw.ustring.lower(ns.name)
local canonicalName = mw.ustring.lower(ns.canonicalName)
mappings[nsname] = {nsname}
if canonicalName ~= nsname then
table.insert(mappings[nsname], canonicalName)
end
for _, alias in ipairs(ns.aliases) do
table.insert(mappings[nsname], mw.ustring.lower(alias))
end
end
end
return mappings
end
return {
argKeys = argKeys,
cfg = cfg,
mappings = getParamMappings()
}
d224f42a258bc308ef3ad8cc8686cd7a4f47d005
Шаблон:Big
10
73
632
119
2024-08-16T16:22:43Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<span style="font-size:120%;">{{{1}}}</span><noinclude>
{{documentation}}
<!-- PLEASE ADD CATEGORIES TO THE /doc SUBPAGE, THANKS -->
</noinclude>
233a0192f59d7a0c6fef6b818e8d1c96d48295d2
Шаблон:Tag
10
72
634
117
2024-08-16T16:22:43Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{#ifeq: {{{style|}}} | regular | <templatestyles src="Модуль:Template call code/styles.css" /> }}<{{#ifeq: {{{style|}}} | regular | span | code }} class="{{#ifeq: {{{wrap|}}} | yes | wrap | nowrap }}" style="{{#switch: {{{style|}}}
| plain = border:none; background:transparent;
| regular =
| {{{style|}}}
}}"><!--
Opening tag
-->{{#switch: {{#if: {{{2|}}} | {{{2|}}} | pair }}
|c|close =
|s|single
|o|open
|p|pair = {{#ifeq: {{{1|tag}}}
| !--
| {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak"><!--</span> | <!-- }}
| {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak"><</span> | < }}{{{1|tag}}}{{#if: {{{params|{{{p|}}}}}} |  {{{params|{{{p|}}}}}} }}
}}
}}<!--
Content between tags
-->{{#switch: {{#if: {{{2|}}} | {{{2|}}} | pair }}
|c|close = {{{content|{{{c|}}}}}}
|s|single =  {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">/></span> | /> }}
|o|open = {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">></span> | > }}{{{content|{{{c|}}}}}}
|p|pair = {{#ifeq: {{{1|tag}}} | !-- || {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">></span> | > }} }}{{{content|{{{c|}}}}}}
}}<!--
Closing tag
-->{{#switch: {{#if: {{{2|}}} | {{{2|}}} | pair }}
|s|single
|o|open =
|c|close
|p|pair = {{#ifeq: {{{1|tag}}}
| !--
| {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak">--></span> | --> }}
| {{#ifeq: {{{style|}}} | regular | <span class="ts-templateCallCode-weak"></</span>{{{1|tag}}}<span class="ts-templateCallCode-weak">></span> | </{{{1|tag}}}> }}
}}
}}<!--
--></{{#ifeq: {{{style|}}} | regular | span | code }}><noinclude>{{doc}}</noinclude>
2818843691a5275eaf013ee7cc1ac4b87c34f392
Шаблон:Документировать
10
18
636
36
2024-08-16T16:22:44Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{ombox
|type = content
|text = '''Этому {{#ifeq: {{NAMESPACE}} | Модуль | модулю | шаблону }} не хватает [[Проект:Технические работы/Шаблоны/Документирование|документации]].'''
|text-small = Вы можете помочь проекту, {{big|'''[[{{SUBJECTSPACE}}:{{PAGENAME:{{{1|{{SUBJECTPAGENAME}}/doc}}}}}|создав описание {{#ifeq: {{NAMESPACE}} | Модуль | модуля | шаблона }}]]'''}}: что он делает, как его использовать, какие параметры он принимает, в какие категории добавляет. Это поможет другим использовать его.
* Не забывайте про [[Проект:Технические работы/Шаблоны/Категоризация|категории]] ({{#ifeq: {{NAMESPACE}} | Модуль || на странице /doc  }}их нужно оборачивать в {{tag|includeonly}}) и интервики.
* Некоторые советы по оформлению есть на странице проекта «[[Проект:Технические работы/Шаблоны/Документирование|Документирование шаблонов]]».
}}<includeonly>{{#if: {{{nocat|}}}{{#ifeq: {{PAGENAME}} | {{SUBPAGENAME}} || {{#ifeq: {{SUBPAGENAME}} | песочница | nocat }} }} ||
{{#switch: {{NAMESPACE}}
| {{ns:10}} = [[Категория:Шаблоны:Недокументированные]]
| {{ns:828}} = {{#ifeq:{{ROOTPAGENAME}}|Песочница||[[Категория:Модули:Недокументированные]]}}
}} }}</includeonly><noinclude>
{{doc-inline}}
Данное сообщение появляется при отсутствующей странице документации, включаемой шаблоном {{t|doc}}.
{{doc-end}}
[[Категория:Шаблоны:Предупреждения]]
[[Категория:Шаблоны:Для документирования шаблонов]]
</noinclude>
7779e82507cacf3a1c77cdb878dd6efafd76b3ce
Модуль:Infobox
828
211
638
471
2024-08-16T16:34:49Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
local p = {};
local yesno = require('Module:Yesno')
local function _renderLine( frame, args, i )
if args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] == '-' then
return ''
elseif args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] ~= '' then
local style = ( args[ 'стиль_заголовков' ] or '' ) .. ( args[ 'стиль_заголовка' .. i ] or '' );
local class = ( args[ 'класс' .. i ] or '' );
return '\n<tr>\n<th colspan="2" scope="colgroup" class="infobox-header ' .. class .. '" style="' .. style .. '">' ..
args[ 'заголовок' .. i ] ..
'</th>\n</tr>';
end
if args[ 'блок' .. i ] and args[ 'блок' .. i ] ~= '' then
return args[ 'блок' .. i ];
end
local text = args[ 'текст' .. i ] or '';
if args[ 'викиданные' .. i ] and args[ 'викиданные' .. i ] ~= '' then
text = frame:expandTemplate{ title = 'Wikidata', args = {
args[ 'викиданные' .. i ],
text,
from = args[ 'from' ] or ''
} };
end
if text ~= '' then
local label = args[ 'метка' .. i ] or '';
local class = args[ 'класс' .. i ] or '';
if string.find(class, 'noplainlist') == nil and string.find(class, 'nofirstlevel') == nil then
class = class .. ' plainlist';
end
if class ~= '' then
class = ' class="' .. class .. '"';
end
local style = ( args[ 'стиль_текстов' ] or '' ) .. ( args[ 'стиль_текста' ] or '' ) .. ( args[ 'стиль_текста' .. i ] or '' );
if label == '' then
style = 'text-align:center;' .. style;
end
if style ~= '' then
style = ' style="' .. style .. '"';
end
if label ~= '' then
local labelClass = args[ 'класс_меток' ] or '';
if string.find(labelClass, 'noplainlist') == nil and string.find(labelClass, 'nofirstlevel') == nil then
labelClass = labelClass .. ' plainlist';
end
if labelClass ~= '' then
labelClass = ' class="' .. labelClass .. '"';
end
local labelStyle = ( args[ 'стиль_меток' ] or '' ) .. ( args[ 'стиль_метки' .. i ] or '' );
if labelStyle ~= '' then
labelStyle = ' style="' .. labelStyle .. '"';
end
return '\n<tr>\n<th scope="row"' .. labelClass .. labelStyle .. '>' .. label .. '</th>' ..
'\n<td' .. class .. style .. '>\n' .. text .. '</td>\n</tr>';
end
return '\n<tr>\n<td colspan="2"' .. class .. style .. '>\n' .. text .. '</td>\n</tr>';
end
return '';
end
local function maxNumber ( args )
local maxNumber = 0
for argName, _ in pairs(args) do
local argNumber = mw.ustring.match(argName, '^[^0-9]+([0-9]+)$')
if argNumber and tonumber(argNumber) > maxNumber then
maxNumber = tonumber(argNumber)
end
end
return maxNumber
end
function p.renderLine( frame )
local args = frame:getParent().args;
return _renderLine(frame, args, '')
end
function p.renderLines( frame )
local args = frame:getParent().args;
local res = ''
local header, text = '', ''
local autoHeaders = yesno(args [ 'автозаголовки' ] or 'false', false)
for i = 1, maxNumber(args) do
if args[ 'заголовок' .. i ] and args[ 'заголовок' .. i ] ~= '' then
if text ~= '' or not autoHeaders then
res = res .. header .. text
end
header, text = _renderLine(frame, args, i), ''
else
text = text .. _renderLine(frame, args, i)
end
end
if text ~= '' or not autoHeaders then
res = res .. header .. text
end
return res
end
return p;
c830c997bd3d15923f347277e3b0ae71b7ba917e
Шаблон:Карточка
10
129
640
606
2024-08-16T16:35:41Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<table class="infobox {{{класс_тела|}}}" style="{{{стиль_тела|}}}" {{#if:{{{имя|}}}|{{#ifeq:{{{имя|}}}|-||data-name="{{{имя}}}"}}}}><!--
Вверху0
-->{{#if:{{{вверху0|}}}|<tr><td colspan="2" class="{{{класс_вверху0|}}}" style="text-align:center; {{{стиль_вверху0|}}}">{{{вверху0}}}</td></tr>}}<!--
Вверху
-->{{#if:{{{вверху|}}}|<tr><th colspan="2" class="infobox-above {{{класс_вверху|}}}" style="{{{стиль_вверху|}}}">{{{вверху}}}</th></tr>}}<!--
Вверху2
-->{{#if:{{{вверху2|}}}|<tr><td colspan="2" class="{{{класс_вверху2|}}}" style="text-align:center; {{{стиль_вверху2|}}}">{{{вверху2}}}</td></tr>}}<!--
Вверху3
-->{{#if:{{{вверху3|}}}|<tr><td colspan="2" class="{{{класс_вверху3|}}}" style="text-align:center; {{{стиль_вверху3|}}}">{{{вверху3}}}</td></tr>}}<!--
Изображение
-->{{#if:{{{изображение|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения|}}}" style="{{{стиль_изображения|}}}"> {{{изображение}}} {{#if:{{{подпись|}}}|
<div class="media-caption" style="{{{стиль_подписи|}}}">{{{подпись}}}</div>}}</td></tr>}}<!--
Изображение2
-->{{#if:{{{изображение2|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения2|}}}" style="{{{стиль_изображения2|}}}"> {{{изображение2}}} {{#if:{{{подпись2|}}}|
<div class="media-caption" style="{{{стиль_подписи2|}}}">{{{подпись2}}}</div>}}</td></tr>}}<!--
Изображение3
-->{{#if:{{{изображение3|}}}|<tr><td colspan="2" class="infobox-image {{{класс_изображения3|}}}" style="{{{стиль_изображения3|}}}"> {{{изображение3}}} {{#if:{{{подпись3|}}}|
<div class="media-caption" style="{{{стиль_подписи3|}}}">{{{подпись3}}}</div>}}</td></tr>}}<!--
Строки
-->{{#invoke:Infobox|renderLines}}<!--
Внизу
-->{{Карточка/внизу|
стиль_внизу_общий={{{стиль_внизу|}}}|
класс_внизу={{{класс_внизу|}}}|
внизу={{{внизу|}}}}}<!--
Внизу N
-->{{#invoke:Transclude|npc|Карточка/внизу|
стиль_внизу_общий={{{стиль_внизу|}}}|
стиль_внизу=|
класс_внизу=|
внизу=}}
</table><includeonly><!--
статьи
-->{{#if:{{NAMESPACE}}||<!--
-->{{#if:{{{имя|}}}||[[Категория:Статьи с шаблонами-карточками без имени]]}}<!--
-->{{#ifeq:{{{имя|}}}|{{subst:PAGENAME}}|[[Категория:Статьи с шаблонами-карточками без имени]]}}<!--
-->}}<!--
шаблоны
-->{{#ifeq:{{NAMESPACENUMBER}}|10|<!--
-->{{#if:{{{имя|}}}||[[Категория:Шаблоны-карточки без имени]]}}<!--
-->{{#ifeq:{{{имя|}}}|{{subst:PAGENAME}}|[[Категория:Шаблоны-карточки без имени]]}}<!--
-->{{#if:{{{название|}}}{{{стиль_названия|}}}|[[Категория:Шаблоны с использованием параметра «название» в шаблоне «Карточка»]]}}<!--
-->{{#if:{{{подпись|}}}{{{стиль_подписи|}}}{{{подпись2|}}}{{{стиль_подписи2|}}}{{{подпись3|}}}{{{стиль_подписи3|}}}|[[Категория:Шаблоны с использованием параметра «подпись» в шаблоне «Карточка»]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_тела|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_названия|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху2|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_вверху3|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи2|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_подписи3|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_заголовков|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_меток|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_текста|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifexpr:{{#invoke:Color_contrast|styleratio|{{{стиль_внизу|}}}}} < 4.5|[[Категория:Потенциально нечитаемые карточки]]}}<!--
-->{{#ifeq:{{{имя|}}}|{{PAGENAME}}| [[Категория:Шаблоны-карточки по алфавиту|{{ucfirst:{{без начала|{{PAGENAME}}|Карточка }}}}]]}}<!--
-->}}<!--
любое пространство имён
-->{{#if:{{{название|}}}{{{стиль_названия|}}}|[[Категория:Страницы с использованием параметра «название» в шаблоне «Карточка»]]}}<!--
-->{{#if:{{{подпись|}}}{{{стиль_подписи|}}}{{{подпись2|}}}{{{стиль_подписи2|}}}{{{подпись3|}}}{{{стиль_подписи3|}}}|[[Категория:Страницы с использованием параметра «подпись» в шаблоне «Карточка»]]}}</includeonly><noinclude>{{doc}}{{Указание авторства русскоязычной Википедии}}</noinclude>
8b14ccc682362e6ed5a194621133805aea17ab0d
Шаблон:OnLua
10
227
642
506
2024-08-16T16:35:45Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
#перенаправление [[Шаблон:Lua]]
b72371e7ae22239863c474a78238171c2bd94c7e
Шаблон:Tlp
10
217
644
483
2024-08-16T16:35:48Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{{{{|safesubst:}}}#invoke: Template call code | withParams | _link = 1 }}<noinclude>{{doc}}</noinclude>
36c309cb28ccf0901f4fff46cbd35cdabcf00661
Шаблон:Карточка/doc
10
226
646
504
2024-08-16T16:35:50Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{docpage}}
{{OnLua|Infobox|renderLines|module2=Transclude|function2=npc}}
{{СИШ}}
Это меташаблон для создания [[Википедия:Шаблоны-карточки|шаблонов-карточек]].
== Параметры ==
=== Служебные ===
; имя: Имя шаблона, необходимое для корректной работы служебных инструментов на всех страницах, где используется шаблон. Для простоты можно использовать <code><nowiki>{{subst:PAGENAME}}</nowiki></code>.
; автозаголовки: Указание «да» приводит к автоматическому скрытию заголовков, после которых, вплоть до следующего заголовка, все поля пусты. Возможно использовать фиктивные заголовки «-» для прерывания области скрытия. Будет работать некорректно, если требуется указать два заголовка подряд — например, при использовании многоуровневых заголовков. В этом случае рекомендуется явно указать «нет» на случай смены значения по умолчанию с «нет» на «да».
; from: Указывается элемент Викиданных, из которого берётся информация.
=== Основные ===
; вверху: Текст, отображаемый вверху таблицы. Обычно это название предмета статьи.
; вверху2: Дополнительный текст, отображаемый вверху таблицы. Обычно используется для оригинального названия.
; вверху3: Дополнительный текст, отображаемый вверху таблицы.
; изображение: Изображение, которое будет отображено под основным заголовком в правой части таблицы (правее заголовков/списков). Параметр ''изображение'' допускает стандартный викикод для отображения. Для разных типов параметра можно использовать {{tl|Форматирование изображения}}. Обычно предпочтительнее использовать код <code><nowiki>{{wikidata|P18|{{{изображение|}}}|caption={{{описание изображения|}}}}}</nowiki></code>.
; подпись: Подпись под изображением. Отображается только в том случае, если задано изображение. При использовании {{tlp|wikidata|P18}} не заполняется.
; изображение2: Дополнительное изображение.
; изображение3: Дополнительное изображение.
; заголовок<sub>n</sub>: Используется для создания заголовков в ряду. Этот и следующие 2 параметра работают при n≥1.
; метка<sub>n</sub>: Используется для подписи текста
; текст<sub>n</sub>: Используется для принятия параметров в специализированных шаблонах-карточках.
; блок<sub>n</sub>: Технический параметр, используется для вставки блоков, заключённых в <tr>, таких как {{t|карточка/блок}}.
; викиданные<sub>n</sub>: Подставляет значение из указанного параметра [[Википедия:Викиданные|Викиданных]] в поле текста, если текст в этой строке определён. Если в поле текста передано значение <code>-</code>, то значение из Викиданных будет скрыто.
; внизу
; внизу<sub>n</sub>: Ячейка во всю ширину таблицы, располагающаяся внизу тела шаблона (то есть под заголовками/метками и текстом).
=== Стили ===
; цвет: Применяется для автоматической раскраски полей «вверху», «внизу» и заголовков через CSS при помощи цветовых тем, имеющихся в шаблоне {{t|Цвет}}
; стиль_тела: Применяется ко всей карточке, обычно используется для указания её ширины, например, <code>width:23em;</code>
; стиль_вверху: Применяется к полю «вверху», например, для указания цвета фона или изменения размера шрифта: <code>font-size:medium;</code>
; стиль_вверху<sub>n</sub>: Используется для изменения стиля дополнительного текста вверху таблицы, например, чтобы убрать курсивное начертание: <code>font-style:normal;</code>
; стиль_изображения: Применяется к ячейке, в которой располагается изображение и его описание
; стиль_изображения<sub>n</sub>: Применяется к ячейке, в которой располагается дополнительное изображение
; стиль_подписи: Применяется к подписи изображения
; стиль_заголовков: С помощью этого стиля можно настроить отображение заголовков, в частности, указать цвет фона: <code>background: #a3eea3;</code>
; стиль_заголовка<sub>n</sub>: Применяется к конкретному заголовку в строке n
; стиль_меток: Применяется к меткам
; стиль_метки<sub>n</sub>: Применяется к конкретной метке в строке n
; стиль_текста: Применяется к тексту
; стиль_текста<sub>n</sub>: Применяется к конкретному тексту в строке n
; стиль_внизу: Эти стили применяются не только в первому ''внизу'', но и ко всем остальным — в отличие от ''стиль_вверху''.
; стиль_внизу<sub>n</sub>: CSS-стили, которые должны быть применены к нижним (указанными параметрами ''внизу'' и ''внизу<sub>n</sub>'') ячейкам.
== Возможности ==
=== Сдвоенные ячейки ===
Если для параметра <code>текст<sub>n</sub></code> значение <code>метка<sub>n</sub></code> не определено, то <code>текст<sub>n</sub></code> автоматически расширяется до 2 ячеек. Для выравнивания по левой стороне можно использовать следующий код:
<pre><nowiki>
|текст2 = {{{параметр|}}}
|стиль_текста2 = text-align:left;
</nowiki></pre>
=== Необязательные ячейки ===
Ряд с меткой, но без текста не будет отображён. Это позволяет легко создавать необязательные параметры в специализированных шаблонах-карточках. Для создания опциональной ячейки используйте параметр следующим образом:
<pre><nowiki>
|метка5 = Население
|текст5 = {{{население|}}}
</nowiki></pre>
Таким образом, если параметр <code>население</code> не будет определён, строка «Население» не будет отображена.
=== Необязательные заголовки ===
Таким же образом можно организовать необязательные заголовки. Следующий пример будет выводить заголовок «Структура», если задан хотя бы один из параметров <code>содержимое</code>, <code>размещение</code>:
<pre><nowiki>
|заголовок5 = {{#if:{{{содержимое|}}}{{{размещение|}}}|Структура}}
|метка6 = Содержимое
|текст6 = {{{содержимое|}}}
|метка7 = Размещение
|текст7 = {{{размещение|}}}
</nowiki></pre>
Если есть заголовокN, то текстN и меткаN игнорируются. Если нет заданного заголовкаN, то показываются текстN и меткаN.
{|
|-
|<pre><nowiki>
|заголовок1 = {{{заголовок1|}}}
|метка1 = {{{метка1|}}}
|текст1 = {{{текст1|}}}
</nowiki></pre>
|}
{|
|-
|<pre><nowiki>
|заголовок1 = заголовок_текст
|метка1 = метка_текст
|текст1 = текст_текст
</nowiki></pre>
|
{| class="wikitable"
|-
! заголовок_текст
|}
|<pre><nowiki>
|заголовок1 =
|метка1 = метка_текст
|текст1 = текст_текст
</nowiki></pre>
|
{| class="wikitable"
|-
| метка_текст|| текст_текст
|}
|}
=== Оформление параметров ===
Для оформления параметра можно использовать [[Википедия:Функции парсера##if|функцию парсера «#if»]]. Например, следующие строки добавят к параметру <code>текст6</code> подпись кг, если этот параметр определён:
<pre><nowiki>
|метка6 = Масса
|текст6 = {{#if:{{{масса|}}} |{{{масса}}} кг}}
</nowiki></pre>
А расстановку ссылок на страницы можно организовать с помощью «[[Википедия:Функции парсера##switch:|#switch]]», например:
<pre><nowiki>
|метка6 = Раса
|текст6 = {{#switch:{{{раса|}}}
|Европеоиды = [[Европеоидная раса|Европеоиды]]
|Негроиды = [[Негроидная раса|Негроиды]]
|Монголоиды = [[Монголоидная раса|Монголоиды]]
|{{{раса|}}}
}}
</nowiki></pre>
== Пустой шаблон ==
<pre>
{{Карточка
|имя = {{subst:PAGENAME}}
|автозаголовки = да
|стиль_вверху =
|стиль_заголовков =
|стиль_внизу =
|вверху =
|вверху2 =
|изображение =
|заголовок1 =
|метка2 =
|текст2 =
|викиданные2 =
|метка3 =
|текст3 =
|викиданные3 =
|метка4 =
|текст4 =
|викиданные4 =
|метка5 =
|текст5 =
|викиданные5 =
|метка6 =
|текст6 =
|викиданные6 =
|метка7 =
|текст7 =
|викиданные7 =
|метка8 =
|текст8 =
|викиданные8 =
|метка9 =
|текст9 =
|викиданные9 =
|метка10 =
|текст10 =
|викиданные10 =
...
|меткаN =
|текстN =
|викиданныеN =
|внизу =
}}<noinclude>
{{doc}}
</noinclude></pre>
{{скрытый|Заголовок=11-20|Содержание=<pre>
|метка11 =
|текст11 =
|викиданные11 =
|метка12 =
|текст12 =
|викиданные12 =
|метка13 =
|текст13 =
|викиданные13 =
|метка14 =
|текст14 =
|викиданные14 =
|метка15 =
|текст15 =
|викиданные15 =
|метка16 =
|текст16 =
|викиданные16 =
|метка17 =
|текст17 =
|викиданные17 =
|метка18 =
|текст18 =
|викиданные18 =
|метка19 =
|текст19 =
|викиданные19 =
|метка20 =
|текст20 =
|викиданные20 =
</pre>}}
{{скрытый||Заголовок=21-30|Содержание=<pre>
|метка21 =
|текст21 =
|викиданные21 =
|метка22 =
|текст22 =
|викиданные22 =
|метка23 =
|текст23 =
|викиданные23 =
|метка24 =
|текст24 =
|викиданные24 =
|метка25 =
|текст25 =
|викиданные25 =
|метка26 =
|текст26 =
|викиданные26 =
|метка27 =
|текст27 =
|викиданные27 =
|метка28 =
|текст28 =
|викиданные28 =
|метка29 =
|текст29 =
|викиданные29 =
|метка30 =
|текст30 =
|викиданные30 =
</pre>}}
{{скрытый||Заголовок=31-40|Содержание=<pre>
|метка31 =
|текст31 =
|викиданные31 =
|метка32 =
|текст32 =
|викиданные32 =
|метка33 =
|текст33 =
|викиданные33 =
|метка34 =
|текст34 =
|викиданные34 =
|метка35 =
|текст35 =
|викиданные35 =
|метка36 =
|текст36 =
|викиданные36 =
|метка37 =
|текст37 =
|викиданные37 =
|метка38 =
|текст38 =
|викиданные38 =
|метка39 =
|текст39 =
|викиданные39 =
|метка40 =
|текст40 =
|викиданные40 =
</pre>}}
{{скрытый||Заголовок=41-50|Содержание=<pre>
|метка41 =
|текст41 =
|викиданные41 =
|метка42 =
|текст42 =
|викиданные42 =
|метка43 =
|текст43 =
|викиданные43 =
|метка44 =
|текст44 =
|викиданные44 =
|метка45 =
|текст45 =
|викиданные45 =
|метка46 =
|текст46 =
|викиданные46 =
|метка47 =
|текст47 =
|викиданные47 =
|метка48 =
|текст48 =
|викиданные48 =
|метка49 =
|текст49 =
|викиданные49 =
|метка50 =
|текст50 =
|викиданные50 =
</pre>}}
{{скрытый||Заголовок=51-60|Содержание=<pre>
|метка51 =
|текст51 =
|викиданные51 =
|метка52 =
|текст52 =
|викиданные52 =
|метка53 =
|текст53 =
|викиданные53 =
|метка54 =
|текст54 =
|викиданные54 =
|метка55 =
|текст55 =
|викиданные55 =
|метка56 =
|текст56 =
|викиданные56 =
|метка57 =
|текст57 =
|викиданные57 =
|метка58 =
|текст58 =
|викиданные58 =
|метка59 =
|текст59 =
|викиданные59 =
|метка60 =
|текст60 =
|викиданные60 =
</pre>}}
== Примерный шаблон для карточки персоны ==
<pre>{{Карточка
|имя = {{subst:PAGENAME}}
|автозаголовки = да
|стиль_вверху =
|стиль_заголовков =
|стиль_внизу =
|вверху = {{карточка/имя|{{{имя|}}}}}
|вверху2 = {{карточка/оригинал имени|{{{оригинал имени|}}}}}
|изображение = {{wikidata|p18|{{{фото|}}}|caption={{{описание изображения|}}}|size={{{ширина|}}}}}
|метка1 = Имя при рождении
|текст1 = {{{имя при рождении|}}}
|викиданные1 = p1477
|метка2 = Дата рождения
|текст2 = {{wikidata/p569|{{{дата рождения|}}}|{{{дата смерти|}}}}}
|метка3 = Место рождения
|текст3 = {{{место рождения|}}}
|викиданные3 = p19
|метка4 = Дата смерти
|текст4 = {{wikidata/p570|{{{дата смерти|}}}|{{{дата рождения|}}}}}
|метка5 = Место смерти
|текст5 = {{{место смерти|}}}
|викиданные5 = p20
|метка6 = Гражданство
|текст6 = {{{гражданство|}}}
|викиданные6 = p27
|метка7 = Сценические имена / Прозвище
|текст7 = {{{прозвище|}}}
|викиданные7 = p1449
|заголовок8 = {{wikidata|p856|{{{сайт|}}}}}
|внизу = {{карточка/Викисклад|{{{викисклад|}}}}}
}}</pre>
Шаблоны {{tl|wikidata/p569}} и {{tl|wikidata/p570}} работают с датами по юлианскому календарю следующим образом:
* <code>13.5.1801 (1)</code> будет отображено как [[13 мая|1 (13) мая]] [[1801 год|1801]];
* <code>12.6.1801 (31.5)</code> будет отображено как 31 мая ([[12 июня]]) [[1801 год|1801]];
* <code>12.1.1802 (31.12.1801)</code> будет отображено как 31 декабря 1801 ([[12 января]] [[1802 год|1802]]).
== Отслеживающие категории, подставляемые шаблоном ==
{{Дерево категорий|Отслеживающие категории:Шаблон:Карточка||1|title=}}
== См. также ==
* [[Википедия:Шаблоны-карточки]]
* {{t|Универсальная карточка}}
* {{t|Навигационная таблица}} — для создания горизонтальных навигационных таблиц (предпочтительнее вертикальных, иногда делаемых на карточке)
* [[:Категория:Шаблоны:Подстраницы шаблона Карточка|Подстраницы шаблона Карточка]]
* [[Участник:Jack who built the house/alignTemplateParameters.js]]
{{Подстраницы шаблона Карточка}}
<includeonly>
[[Категория:Шаблоны-карточки|*]]
[[Категория:Шаблоны:Мета-шаблоны]]
</includeonly>
f1b3e8ad443b38b993ae6112a8adda8827efe76f
Шаблон:Карточка/внизу
10
137
648
317
2024-08-16T16:35:50Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{#if:{{{внизу|}}}|<tr><td colspan="2" class="infobox-below {{{класс_внизу|}}}" style="{{{стиль_внизу_общий|}}};{{{стиль_внизу|}}}">{{{внизу|}}}</td></tr>}}</includeonly><noinclude>
{{doc}}
</noinclude>
169fb2d10b0847c2fd677eda9f159ba99025198f
Шаблон:Конец скрытого блока
10
199
650
445
2024-08-16T16:35:50Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly></div></div></includeonly><noinclude>
{{doc|Шаблон:Начало скрытого блока/doc}}</noinclude>
2da6ac8eb0812fb4183a70b516009d40920e281f
Шаблон:Начало скрытого блока
10
196
652
439
2024-08-16T16:35:51Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly><templatestyles src="Шаблон:Скрытый блок/styles.css" /><!--
--><div class="mw-collapsible {{#switch: {{{состояние|{{{state|}}}}}} | expanded | autocollapse = {{{состояние|{{{state|}}}}}} | mw-collapsed }} ts-Скрытый_блок ts-Скрытый_блок-{{#switch: {{{тип|{{{type|}}}}}} | gray | transparent = {{{тип|{{{type|}}}}}} | gray }} ts-Скрытый_блок-{{#switch: {{{Ссылка|{{{ссылка|}}}}}} | none = none | right | left = {{{Ссылка|{{{ссылка|}}}}}} | right }}HideLink {{{класс_тела|{{{класс тела|}}}}}}" style="{{ifempty |до = border: | {{{Рамка|{{{border|{{{рамка|}}}}}}}}} |после=;}}{{{frame-style|{{{стиль_тела|{{{стиль тела|}}}}}}}}}"><!--
--><div class="ts-Скрытый_блок-title {{#switch: {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}} | none = none | left | right = ts-Скрытый_блок-title-{{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}}Title }} {{{класс_заголовка|{{{класс заголовка|}}}}}}" style="<!--
-->{{ifempty |до = background-color: | {{{Фон_заголовка|{{{bg1|{{{фон_заголовка|{{{фон заголовка|}}}}}}}}}}}} |после=;}}<!--
-->{{ifempty |до = text-align: | {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}} |после=;}}<!--
-->{{ifempty |до = font-weight: | {{{Шрифт_заголовка|{{{шрифт_заголовка|{{{шрифт заголовка|}}}}}}}}} |после=;}}<!--
-->{{ifempty |до = font-style: | {{{Наклон_заголовка|{{{наклон_заголовка|{{{наклон заголовка|}}}}}}}}} |после=;}}<!--
-->{{{Стиль_заголовка|{{{extra1|{{{стиль_заголовка|{{{стиль заголовка|}}}}}}}}}}}}"><!--
-->{{{Заголовок|{{{заголовок|{{{Заглавие|{{{заглавие|{{{Название|{{{название|{{{header|{{{title|{{{1}}}}}}}}}}}}}}}}}}}}}}}}}}}<!--
--><div class="mw-collapsible-toggle-placeholder"></div></div><!--
--><div class="mw-collapsible-content {{{класс_текста|{{{класс текста|}}}}}}" style="<!--
-->{{ifempty |до = background-color: | {{{Фон_текста|{{{bg2|{{{фон_текста|{{{фон текста|}}}}}}}}}}}} |после=;}}<!--
-->{{ifempty |до = font-weight: | {{{Шрифт_текста|{{{шрифт_текста|{{{шрифт текста|}}}}}}}}} |после=;}}<!--
-->{{ifempty |до = font-style: | {{{Наклон_текста|{{{наклон_текста|{{{наклон текста|}}}}}}}}} |после=;}}<!--
-->{{ifempty |до = text-align: | {{{Выравнивание_текста|{{{ta2|{{{выравнивание_текста|{{{выравнивание текста|}}}}}}}}}}}} |после=;}}<!--
-->{{{Стиль_текста|{{{extra2|{{{стиль_текста|{{{стиль текста|}}}}}}}}}}}}"><!--
--></includeonly><noinclude>
{{doc}}
</noinclude>
3b96bb802b522e629c41cddc5d44dfb2a9eb462a
Шаблон:Скрытый
10
203
654
453
2024-08-16T16:35:51Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
#перенаправление [[Шаблон:Скрытый блок]]
97cc939c1c8ece875b2ec360f85980bd6f1bbed7
Шаблон:Скрытый блок
10
200
656
447
2024-08-16T16:35:52Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{Начало скрытого блока
|id = {{{id|}}}
|тип = {{{тип|{{{type|}}}}}}
|состояние = {{{state|{{{состояние|collapsed}}}}}}
|класс_тела = {{{класс_тела|{{{класс тела|}}}}}}
|стиль_тела = {{{frame-style|{{{стиль_тела|{{{стиль тела|}}}}}}}}}
|рамка = {{{Рамка|{{{border|{{{рамка|}}}}}}}}}
|заголовок = {{{Заголовок|{{{заголовок|{{{Заглавие|{{{заглавие|{{{Название|{{{название|{{{header|{{{title|{{{1}}}}}}}}}}}}}}}}}}}}}}}}}}}
|ссылка = {{{Ссылка|{{{ссылка|}}}}}}
|класс_заголовка = {{{класс_заголовка|{{{класс заголовка|}}}}}}
|шрифт_заголовка = {{{Шрифт_заголовка|{{{шрифт_заголовка|{{{шрифт заголовка|}}}}}}}}}
|наклон_заголовка = {{{Наклон_заголовка|{{{наклон_заголовка|{{{наклон заголовка|}}}}}}}}}
|фон_заголовка = {{{Фон_заголовка|{{{bg1|{{{фон_заголовка|{{{фон заголовка|}}}}}}}}}}}}
|выравнивание_заголовка = {{{Выравнивание_заголовка|{{{ta1|{{{выравнивание_заголовка|{{{выравнивание заголовка|}}}}}}}}}}}}
|стиль_заголовка = {{{title-style|{{{Стиль_заголовка|{{{extra1|{{{стиль_заголовка|{{{стиль заголовка|}}}}}}}}}}}}}}}
|класс_текста = {{{класс_текста|{{{класс текста|}}}}}}
|шрифт_текста = {{{Шрифт_текста|{{{шрифт_текста|{{{шрифт текста|}}}}}}}}}
|наклон_текста = {{{Наклон_текста|{{{наклон_текста|{{{наклон текста|}}}}}}}}}
|фон_текста = {{{Фон_текста|{{{bg2|{{{фон_текста|{{{фон текста|}}}}}}}}}}}}
|выравнивание_текста = {{{Выравнивание_текста|{{{ta2|{{{выравнивание_текста|{{{выравнивание текста|}}}}}}}}}}}}
|стиль_текста = {{{content-style|{{{Стиль_текста|{{{extra2|{{{стиль_текста|{{{стиль текста|}}}}}}}}}}}}}}}}}
{{{content|{{{Содержание|{{{содержание|{{{2}}}}}}}}}}}}
{{#if: {{{footer|}}} | <div style="{{{footer-style|{{{title-style|}}}}}}">{{{footer}}}</div> }}
{{Конец скрытого блока}}<noinclude>
{{doc}}
</noinclude>
792dc9fb2eb659877e2e758f4ce405e1d3f8352b
Модуль:Transclude
828
144
658
331
2024-08-16T16:35:58Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
local p={}
-- Вызывает внутренний шаблон с аргументами объемлющего шаблона
function p.call(frame)
local template = frame.args[1]
local args = frame:getParent().args
return frame:expandTemplate{ title=template, args=args }
end
-- Общая реализация для forall и call
local function forallImpl(args, separator, conjunction, func)
-- нумерованные ключи из args
local keys = {}
-- перебор в произвольном порядке, даже для нумерованных ключей
for key, value in pairs(args) do
if type(key) == 'number' and value and value ~= '' then
table.insert(keys, key)
end
end
table.sort(keys)
local results = {}
for _, key in ipairs(keys) do
local value = func(args[key])
table.insert(results, value)
end
return mw.text.listToText(results, separator, conjunction)
end
-- Вызывает внутренний шаблон, передавая ему нумерованные параметры объемлющего шаблона по-одному
function p.forall(frame)
local template = frame.args[1]
local separator = frame.args.separator or ''
local conjunction = frame.args.conjunction or separator
local args = frame:getParent().args
local func = function(value)
return frame:expandTemplate{ title = template, args = {value} } -- или другой frame?
end
return forallImpl(args, separator, conjunction, func)
end
-- Берёт нумерованные аргументы объемлющего шаблона и склеивает их в единую строку
function p.join(frame)
local separator = frame.args[1] or ''
local conjunction = frame.args[2] or separator
local args = frame:getParent().args
local func = function(value)
return value
end
return forallImpl(args, separator, conjunction, func)
end
-- Служебная функция: удаляет дубликаты из отсортированного массива с нумерованными индексами
local function deleteDuplicates(args)
local res = {}
for key, value in pairs(args) do
if args[key+1] ~= value then
table.insert(res, value)
end
end
return res
end
-- Вызывает внутренний шаблон несколько раз, передавая в него блоки аргументов объемлющего шаблона
function p.npc(frame)
local args = frame:getParent().args
local templateFrame = frame:getParent()
local template = frame.args[1]
-- определение, блоки аргументов с какими номерами нужны:
-- если в объемлющем шаблоне есть "параметр12" и в вызове модуля есть "параметр", то вызывается 12-й блок
local nums = {}
for key, _ in pairs(args) do
local main, num = string.match(key, '^(.-)%s*(%d*)$')
num = tonumber(num)
-- учитывать "параметр12", только если задано "параметр"
if num and frame.args[main] then
table.insert(nums, num)
end
end
table.sort(nums)
nums = deleteDuplicates(nums)
-- проходить по нужным номерам блоков по возрастанию и однократно
-- подставлять в шаблон:
-- 1. общие аргументы данного модуля
-- 2. аргументы объемлющего шаблона вида "параметр12" как "параметр" в 12-й блок
local results = {}
for _, blockNum in ipairs(nums) do
-- общие аргументы модуля, которые передаются в каждый блок
local blockArgs = mw.clone(frame.args)
-- metatable ломает expandTemplate
setmetatable(blockArgs, nil)
for key, value in pairs(args) do
local main, num = string.match(key, '^(.-)%s*(%d*)$')
num = tonumber(num)
-- передавать "параметр12" как "параметр" в 12-й блок, только если есть "параметр" в вызове модуля
if blockNum == num and frame.args[main] then
blockArgs[main] = value
end
end
local blockText = templateFrame:expandTemplate{ title=template; args=blockArgs }
table.insert(results, blockText)
end
return table.concat(results)
end
-- Действует аналогично forall по числовой переменной, изменяющейся (по умолчанию, от 1) до f.args[2].
function p.cycle(f)
local tf,ac,op=f:getParent(), {}, f.args.output or 'inline';
local sep='';
if op == 'newline' then
sep='\n';
end
for p,k in pairs(f.args) do
if type(p)=='number' then
if p>2 then ac[p-1]=k end
else ac[p]=k
end
end
local s,fh = f.args[2]:match('^%s*(%-?%d+)%s*%.%.') or 1,
f.args[2]:match('%.%.%s*(%S.*)%s*$') or f.args[2] or '';
fh=tonumber(fh) or fh:match('^%s*(.-)%s*$');
s=tonumber(s);
local acr={};
if not s then error('Начало цикла «'..s..'» — не число') end
local function dc(order)
local r=tf:expandTemplate{ title=f.args[1]; args={s,unpack(ac)} }
if order == 'desc' then
s=s-1;
else
s=s+1;
end
if r~='' then table.insert(acr,r); return r end
end
if type(fh)=='number' then
if fh > s then
while s<=fh do dc('asc') end
else
while s>=fh do dc('desc') end
end
elseif fh~='' then
while tf:expandTemplate{ title=fh; args={s,unpack(ac)} } do dc('asc') end
else
while dc('asc') do end
end
return table.concat(acr, sep)
end
return p
c17cfab4cebc23157f5ab8d18c7e4f5c273bfa59
Модуль:Template call code
828
126
659
572
2024-08-16T16:38:22Z
DuOfOrl
5
Scribunto
text/plain
local getArgs = require('Module:Arguments').getArgs
local ru = mw.language.new('ru')
local p = {}
-- Используется для того, чтобы можно было удалять элементы из таблицы
local function copy(other)
local res = {}
for k, v in pairs(other) do
res[k] = v
end
return res
end
local function makeInvokeFunc(funcName)
return function (frame)
local args = copy(getArgs(frame, {
trim = false,
removeBlanks = false
}))
return p[funcName](args)
end
end
p.withoutParams = makeInvokeFunc('_withoutParams')
function p._withoutParams(args)
local name = args[1]
table.remove(args, 1)
-- Вещи типа «=» в первом параметре
if not name then
for k, v in pairs(args) do
if not k:find('^_') then
name = k .. '=' .. v
args[k] = nil
break
end
end
end
local flags = {}
for i, v in ipairs(args) do
if v == 'nl' or v == 'nolink' then
flags.noLink = true
elseif v == 's' then
flags.subst = true
elseif v == 'п' then
flags.podst = true
elseif v == 'g' then
flags.global = true
elseif v == 'nav' then
flags.nav = true
elseif v == 'noredir' then
flags.noRedirect = true
elseif v == 'u' then
flags.ucFirst = true
elseif v == 'b' then
flags.black = true
end
end
if name then
local trimmedName = mw.text.trim(name)
if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'subst:' then
flags.subst = true
name = mw.ustring.sub(trimmedName, 7)
end
if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'подст:' then
flags.podst = true
name = mw.ustring.sub(trimmedName, 7)
end
end
if args.text == '' then
args.text = nil
end
if args.comment == '' then
args.comment = nil
end
if args.lang == '' then
args.lang = nil
end
if args.sister == '' then
args.sister = nil
end
local currentTitle = mw.title.getCurrentTitle()
-- При опущенном первом параметре берём имя шаблона из названия страницы
if name == '' or not name then
local currentTitleRoot = currentTitle.rootText
if not flags.ucFirst and
((ru:uc(currentTitleRoot) ~= currentTitleRoot and
-- Книга:Литературное наследство, TranslateDate
not mw.ustring.match(currentTitleRoot, '^[А-Яа-яA-Za-z]+:?[А-ЯA-Z]')
) or
#currentTitleRoot == 1
)
then
name = ru:lcfirst(currentTitleRoot)
else
name = currentTitleRoot
end
end
local global = flags.global or mw.ustring.sub(name, 1, 1) == ':'
-- Начинаем собирать код
local linkBody, titleObject, linkBegin, linkDivider, linkEnd
local prefixes = {}
if args.lang then
table.insert(prefixes, args.lang)
end
if args.sister then
table.insert(prefixes, args.sister)
end
linkBody = table.concat(prefixes, ':')
if #linkBody ~= 0 then
linkBody = ':' .. linkBody
end
if mw.ustring.sub(name, 1, 1) ~= ':' then
linkBody = linkBody .. ':'
end
if not global then
linkBody = linkBody .. 'Template:'
end
linkBody = linkBody .. name
titleObject = mw.title.new(linkBody)
local noLink = flags.noLink or currentTitle == titleObject
local takeBracketsInLink = not noLink and
mw.ustring.len(name) == 1 and
not flags.black and
not flags.subst and
not flags.podst
if not noLink then
if not flags.noRedirect or (
flags.noRedirect and
not args.lang and
not args.sister and
not titleObject.exists
) then
linkBegin = '[['
linkEnd = ']]'
linkDivider = '|'
else
linkBegin = '['
linkEnd = ']'
linkDivider = ' '
linkBody = titleObject:fullUrl('redirect=no')
end
end
local text = ''
if flags.nav and currentTitle == titleObject then
text = text .. '\'\'\''
end
if not flags.black then
text = text .. '<span class="wp-templatelink">'
end
text = text .. '{'
if not takeBracketsInLink then
text = text .. '{'
end
if flags.subst then
text = text .. 'subst:'
elseif flags.podst then
text = text .. 'подст:'
end
if not flags.black then
text = text .. '</span>'
end
text = text .. '<span data-navboxnavigation-link="0">'
local commentedLabel
if args.comment then
-- https://phabricator.wikimedia.org/T200704
-- commentedLabel = mw.getCurrentFrame():expandTemplate({title = 'comment', args = {(args.text or name), args.comment}})
commentedLabel = '<span class="commentedText" title="' .. args.comment .. '" style="border-bottom: 1px dotted; cursor: help;">' ..
(args.text or name) ..
'</span>'
end
local label = (commentedLabel or args.text or name)
if not noLink then
if flags.noRedirect then
text = text .. '<span class="plainlinks">'
end
text = text .. linkBegin .. linkBody .. linkDivider
if not noLink and takeBracketsInLink then
text = text .. '<span class="wp-templatelink">{</span>'
end
text = text .. label
if not noLink and takeBracketsInLink then
text = text .. '<span class="wp-templatelink">}</span>'
end
text = text .. linkEnd
if flags.noRedirect then
text = text .. '</span>'
end
else
text = text .. label
end
text = text .. '</span>'
if not flags.black then
text = text .. '<span class="wp-templatelink">'
end
text = text .. '}'
if not takeBracketsInLink then
text = text .. '}'
end
if not flags.black then
text = text .. '</span>'
end
if flags.nav and currentTitle == titleObject then
text = text .. '\'\'\''
end
return text
end
function addParams(args, params)
local text, equals_pos, param, value = '', 0, '', ''
function addPipe()
if params.spaced then
text = text .. ' '
end
text = text .. '<span'
if not params.black then
text = text .. ' class="wp-templatelink"'
end
if not params.spaced then
text = text .. ' style="margin:0 2px;"'
end
text = text .. '>|</span>'
end
for k, v in pairs(args) do
if type(k) == 'number' then -- Неименованные параметры
equals_pos = v:find('=')
if equals_pos and v:find('{{=}}') == equals_pos - 2 then
equals_pos = nil
end
if equals_pos then -- Содержащие «=» преобразуем в именованные
param = v:sub(1, equals_pos - 1)
value = v:sub(equals_pos + 1)
addPipe()
text = text .. param .. '=' .. value
else -- Истинно неименованные
addPipe()
text = text .. v
end
elseif not k:find('^_') then -- Именованные параметры, исключая модификаторы внешнего вида
addPipe()
text = text .. k .. '=' .. v
end
end
return text
end
p.withParams = makeInvokeFunc('_withParams')
function p._withParams(args)
local name = args[1]
table.remove(args, 1)
-- Вещи типа «=» в первом параметре
if not name then
for k, v in pairs(args) do
if not k:find('^_') then
name = k .. '=' .. v
args[k] = nil
break
end
end
end
local optpText
if name then
local spanOffset = mw.ustring.find(name, '<span') -- След использования шаблона optp
if spanOffset then
optpText = mw.ustring.sub(name, spanOffset)
name = mw.ustring.sub(name, 1, spanOffset - 1)
end
end
local yesno = require('Module:Yesno')
local nobr = yesno(args._nobr, false)
local tag = args._tag or 'span'
local style = args._style
local spaced = yesno(args._spaced, false)
local subst = yesno(args._s, false)
local podst = yesno(args['_п'], false)
local global = yesno(args._g, false) or name and mw.ustring.sub(name, 1, 1) == ':'
local lang = args._lang
local sister = args._sister
local nav = yesno(args._nav, false)
local ucFirst = yesno(args._u, false)
local black = yesno(args._b, false) or tag ~= 'span'
local noLink = yesno(args._nolink or args._nl, false) or not yesno(args._link, false)
local textInPlaceOfName = args._text
local comment = args._comment
local noRedirect = yesno(args._noredir, false)
local prefix = args._prefix
local postfix = args._postfix
if textInPlaceOfName == '' then
textInPlaceOfName = nil
end
if comment == '' then
comment = nil
end
if lang == '' then
lang = nil
end
if sister == '' then
sister = nil
end
if name then
local trimmedName = mw.text.trim(name)
if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'subst:' then
subst = true
name = mw.ustring.sub(trimmedName, 7)
end
if ru:lc(mw.ustring.sub(trimmedName, 1, 6)) == 'подст:' then
podst = true
name = mw.ustring.sub(trimmedName, 7)
end
end
local currentTitle = mw.title.getCurrentTitle()
-- При опущенном первом параметре берём имя шаблона из названия страницы
if name == '' or not name then
local currentTitleRoot = currentTitle.rootText
if not ucFirst and
((ru:uc(currentTitleRoot) ~= currentTitleRoot and
-- Книга:Литературное наследство, TranslateDate
not mw.ustring.match(currentTitleRoot, '^[А-Яа-яA-Za-z]+:?[А-ЯA-Z]')
) or
#currentTitleRoot == 1
)
then
name = ru:lcfirst(currentTitleRoot)
else
name = currentTitleRoot
end
end
-- Начинаем собирать код
local linkBody, titleObject, linkBegin, linkDivider, linkEnd
local prefixes = {}
if lang then
table.insert(prefixes, lang)
end
if sister then
table.insert(prefixes, sister)
end
linkBody = table.concat(prefixes, ':')
if #linkBody ~= 0 then
linkBody = ':' .. linkBody
end
if mw.ustring.sub(name, 1, 1) ~= ':' then
linkBody = linkBody .. ':'
end
if not global then
linkBody = linkBody .. 'Template:'
end
linkBody = linkBody .. name
titleObject = mw.title.new(linkBody)
local noLink = noLink or currentTitle == titleObject
local takeBracketsInLink = not noLink and
mw.ustring.len(name) == 1 and
not black and
not subst and
not podst
if not noLink then
if not noRedirect or (
noRedirect and
not lang and
not sister and
not titleObject.exists
) then
linkBegin = '[['
linkEnd = ']]'
linkDivider = '|'
else
linkBegin = '['
linkEnd = ']'
linkDivider = ' '
linkBody = titleObject:fullUrl('redirect=no')
end
end
local text = ''
if tag then
text = text .. '<' .. tag .. ' class="templateCallCode'
if nobr then
text = text .. ' nowrap'
end
text = text .. '"'
if style then
text = text .. ' style="' .. style .. '"'
end
text = text .. '>'
end
if prefix then
text = text .. prefix
end
if not black then
text = text .. '<span class="wp-templatelink">'
end
text = text .. '{{'
if subst then
text = text .. 'subst:'
elseif podst then
text = text .. 'подст:'
end
if not black then
text = text .. '</span>'
end
if nav and currentTitle == titleObject then
text = text .. '\'\'\''
end
local commentedLabel
if comment then
-- https://phabricator.wikimedia.org/T200704
-- commentedLabel = mw.getCurrentFrame():expandTemplate({title = 'comment', args = {(text or name), comment}})
commentedLabel = '<span class="commentedText" title="' .. comment .. '" style="border-bottom: 1px dotted; cursor: help;">' ..
(textInPlaceOfName or name) ..
'</span>'
end
local label = (commentedLabel or textInPlaceOfName or name)
if not noLink then
if noRedirect then
text = text .. '<span class="plainlinks">'
end
text = text .. linkBegin .. linkBody .. linkDivider .. label .. linkEnd
if noRedirect then
text = text .. '</span>'
end
else
text = text .. label
end
if nav and currentTitle == titleObject then
text = text .. '\'\'\''
end
if optpText then
text = text .. optpText
end
text = text .. addParams(args, {
spaced = spaced,
black = black,
})
if spaced then
text = text .. ' '
end
if not black then
text = text .. '<span class="wp-templatelink">'
end
text = text .. '}}'
if not black then
text = text .. '</span>'
end
if postfix then
text = text .. postfix
end
if tag then
text = text .. '</' .. tag .. '>'
end
return text
end
p.onlyParams = makeInvokeFunc('_onlyParams')
function p._onlyParams(args)
local span = mw.html.create('span')
span:css( 'color', mw.getCurrentFrame():expandTemplate({ title = 'optp/color' }) )
local yesno = require('Module:Yesno')
span:wikitext(addParams(args, {
spaced = yesno(args._spaced, false),
black = true,
}))
return tostring(span)
end
return p
0b9f3af403c5d8136788ce6aae12a9b96ee4fe52
Модуль:Navbox
828
82
662
139
2024-08-16T16:47:54Z
DuOfOrl
5
Scribunto
text/plain
--
-- Реализует {{навигационная таблица}}, {{подгруппы навигационной таблицы}} и {{навигационная таблица с блоками}}.
-- Основной объём кода заимствован из английского Module:Navbox.
--
local p = {}
local getArgs -- lazily initialized
local yesno -- lazily initialized
local styleratio
local ODD_EVEN_MARKER = '\127_ODDEVEN_\127'
local RESTART_MARKER = '\127_ODDEVEN0_\127'
local REGEX_MARKER = '\127_ODDEVEN(%d?)_\127'
-- общие параметры для всех шаблонов
local commonAliases = {
name = {'name', 'имя'},
navigation = {'navigation', 'навигация'},
navbar = {'navbar', 'ссылка_на_просмотр'},
state = {'state'},
orphan = {'orphan'},
tracking = {'tracking'},
border = {'border', 1},
title = {'title', 'заголовок'},
titlegroup = {'titlegroup'},
above = {'above', 'вверху'},
image = {'image', 'изображение'},
imageleft = {'imageleft', 'изображение2', 'изображение_слева'},
below = {'below', 'внизу'},
bodyclass = {'bodyclass', 'класс_тела'},
titleclass = {'titleclass', 'класс_заголовка'},
titlegroupclass = {'titlegroupclass'},
aboveclass = {'aboveclass', 'класс_вверху'},
belowclass = {'belowclass', 'класс_внизу'},
groupclass = {'groupclass', 'класс_групп'},
listclass = {'listclass', 'класс_списков'},
imageclass = {'imageclass', 'класс_изображения'},
basestyle = {'basestyle', 'стиль', 'стиль_базовый'},
bodystyle = {'style', 'bodystyle', 'стиль_тела'},
titlestyle = {'titlestyle', 'стиль_основного_заголовка', 'стиль_заголовка'},
titlegroupstyle = {'titlegroupstyle'},
innerstyle = {'innerstyle'},
abovestyle = {'abovestyle', 'стиль_вверху'},
belowstyle = {'belowstyle', 'стиль_внизу'},
imagestyle = {'imagestyle', 'стиль_изображения'},
imageleftstyle = {'imageleftstyle', 'imagestyle2', 'стиль_изображения_слева'},
}
-- параметры {{навигационная таблица}} и {{подгруппы навигационной таблицы}}
local standardAliases = {
groupstyle = {'groupstyle', 'стиль_заголовков', 'стиль_групп'},
liststyle = {'liststyle', 'стиль_списков'},
evenodd = {'evenodd', 'чётные_нечётные', 'четные_нечетные'},
groupwidth = {'groupwidth', 'ширина_групп'},
listpadding = {'listpadding', 'отступ_списков'},
}
-- параметры {{навигационная таблица}} и {{подгруппы навигационной таблицы}} с нумерацией
local standardElementAliases = {
group = {'group%s', 'заголовок%s', 'группа%s'},
list = {'list%s', 'список%s'},
groupstyle = {'group%sstyle', 'стиль_заголовка%s', 'стиль_группы%s'},
liststyle = {'list%sstyle', 'стиль_списка%s'},
listpadding = {'list%spadding'}
}
-- параметры {{навигационная таблица с блоками}}
-- с нижнего подчеркивания начинаются параметры, конфликтующие с standardAliases
local groupsParentAliases = {
selected = {'selected', 'открытый_блок', 'развернуть'},
secttitlestyle = {'secttitlestyle', 'стиль_заголовков'},
_groupstyle = {'groupstyle', 'стиль_блоков'},
_liststyle = {'liststyle', 'стиль_списков', 'contentstyle'},
_listpadding = {'listpadding', 'отступ_списка', 'отступ_списков'}
}
-- параметры {{навигационная таблица с блоками}} с нумерацией
local groupsChildAliases = {
groupname = {'abbr%s', 'имя_блока%s', 'аббр%s'},
state = {'state%s'},
title = {'group%s', 'блок%s', 'заголовок%s', 'группа%s', 'sect%s', 'section%s', 'секция%s'},
list1 = {'list%s', 'список%s', 'content%s'},
image = {'image%s', 'изображение%s'},
imageleft = {'imageleft%s', 'изображение_слева%s'},
secttitlestyle = {'sect%stitlestyle', 'стиль%sзаголовка', 'стиль_секции%s'},
groupstyle = {'group%sstyle', 'стиль%sблока', 'стиль_группы%s', 'стиль_блока%s'},
liststyle = {'list%sstyle', 'стиль%sсписка', 'стиль_списка%s', 'content%sstyle'},
color = {'цвет%s'}
}
local function checkAliases(args, aliases, index)
for _, alias in ipairs(aliases) do
local arg
if index then
arg = args[string.format(alias, index)]
else
arg = args[alias]
end
if arg then
return arg
end
end
return nil
end
local function checkElAliases(args, name, index)
return checkAliases(args, standardElementAliases[name], index)
end
local function concatStyles(t)
local res
for k, v in pairs(t) do
if v then
res = res and res .. ';' .. v or v
end
end
return res
end
local function striped(wikitext, args)
-- Return wikitext with markers replaced for odd/even striping.
-- Child (subgroup) navboxes are flagged with a category that is removed
-- by parent navboxes. The result is that the category shows all pages
-- where a child navbox is not contained in a parent navbox.
local orphanCat = '[[Категория:Навигационные шаблоны без родителя]]'
if args.border == 'subgroup' and args.orphan ~= 'yes' then
-- No change; striping occurs in outermost navbox.
return wikitext .. orphanCat
end
local first, second = 'odd', 'even'
if args.evenodd then
if args.evenodd == 'swap' then
first, second = second, first
else
first = args.evenodd
second = first
end
end
local changer
if first == second then
changer = first
else
local index = 0
changer = function (code)
if code == '0' then
-- Current occurrence is for a group before a nested table.
-- Set it to first as a valid although pointless class.
-- The next occurrence will be the first row after a title
-- in a subgroup and will also be first.
index = 0
return first
end
index = index + 1
return index % 2 == 1 and first or second
end
end
local regex = orphanCat:gsub('([%[%]])', '%%%1')
return (wikitext:gsub(regex, ''):gsub(REGEX_MARKER, changer)) -- () omits gsub count
end
local function addNewline(s)
if s:match('^[*:;#]') or s:match('^{|') then
return '\n' .. s ..'\n'
else
return s
end
end
local function renderNavBar(titleCell, args)
if args.navbar ~= 'off' and args.navbar ~= 'plain'
and (args.name or not mw.getCurrentFrame():getParent():getTitle():gsub('/песочница$', '') == 'Шаблон:Навигационная таблица') then
-- Check color contrast of the gear icon
if not styleratio then
styleratio = require('Module:Color contrast')._styleratio
end
local gearColor = ''
local contrastStyle = args.titlestyle or args.basestyle
local gearStyleBlack = (contrastStyle and mw.text.unstripNoWiki(contrastStyle) .. '; color:#666;' or '')
local gearStyleWhite = (contrastStyle and mw.text.unstripNoWiki(contrastStyle) .. '; color:#fff;' or '')
if styleratio{gearStyleBlack} < styleratio{gearStyleWhite} then
gearColor = ' white'
end
local gear = string.format(
'[[Файл:Wikipedia interwiki section gear icon%s.svg|14px|Просмотр этого шаблона|link=Шаблон:%s|alt=⛭]]',
gearColor, args.name
)
--- Gear creation
titleCell
:tag('span')
:addClass('navbox-gear')
:css('float', 'left')
:css('text-align', 'left')
:css('width', '5em')
:css('margin-right', '0.5em')
:wikitext(gear)
end
end
--
-- Title row
--
local function renderTitleRow(tbl, args)
if not args.title then return end
local titleRow = tbl:tag('tr')
if args.titlegroup then
titleRow
:tag('th')
:attr('scope', 'row')
:addClass('navbox-group')
:addClass(args.titlegroupclass)
:cssText(args.basestyle)
:cssText(args.groupstyle)
:cssText(args.titlegroupstyle)
:wikitext(args.titlegroup)
end
local titleCell = titleRow:tag('th'):attr('scope', 'colgroup')
if args.titlegroup then
titleCell
:css('border-left', '2px solid #fdfdfd')
:css('width', '100%')
end
local titleColspan = 2
if args.imageleft then titleColspan = titleColspan + 1 end
if args.image then titleColspan = titleColspan + 1 end
if args.titlegroup then titleColspan = titleColspan - 1 end
titleCell
:cssText(args.basestyle)
:cssText(args.titlestyle)
:addClass('navbox-title')
:attr('colspan', titleColspan)
renderNavBar(titleCell, args)
titleCell
:tag('div')
:attr('id', mw.uri.anchorEncode(args.title))
:addClass(args.titleclass)
:css('font-size', '114%')
:css('margin', '0 5em')
:wikitext(addNewline(args.title))
end
--
-- Above/Below rows
--
local function getAboveBelowColspan(args)
local ret = 2
if args.imageleft then ret = ret + 1 end
if args.image then ret = ret + 1 end
return ret
end
local function renderAboveRow(tbl, args)
if not args.above then return end
tbl:tag('tr')
:tag('td')
:addClass('navbox-abovebelow')
:addClass(args.aboveclass)
:cssText(args.basestyle)
:cssText(args.abovestyle)
:attr('colspan', getAboveBelowColspan(args))
:tag('div')
:wikitext(addNewline(args.above))
end
local function renderBelowRow(tbl, args)
if not args.below then return end
tbl:tag('tr')
:tag('td')
:addClass('navbox-abovebelow')
:addClass(args.belowclass)
:cssText(args.basestyle)
:cssText(args.belowstyle)
:attr('colspan', getAboveBelowColspan(args))
:tag('div')
:wikitext(addNewline(args.below))
end
--
-- List rows
--
local function haveSubgroups(args)
for i = 1, 23 do
if checkElAliases(args, 'group', i) and checkElAliases(args, 'list', i) then
return true
end
end
return false
end
local function renderListRow(tbl, args, index, rowspan, rowArgs)
local row = tbl:tag('tr')
if index == 1 and args.imageleft then
row
:tag('td')
:addClass('navbox-image')
:addClass(args.imageclass)
:css('width', '1px')
:css('padding', '0px 7px 0px 0px')
:cssText(args.imageleftstyle)
:attr('rowspan', rowspan)
:tag('div')
:wikitext(addNewline(args.imageleft))
end
if rowArgs.group then
local groupCell = row:tag('th')
groupCell
:attr('scope', 'row')
:addClass('navbox-group')
:addClass(args.groupclass)
:cssText(args.basestyle)
:css('width', args.groupwidth or '1px') -- If groupwidth not specified, minimize width
groupCell
:cssText(args.groupstyle)
:cssText(rowArgs.groupstyle)
:wikitext(rowArgs.group)
end
local listCell = row:tag('td')
if rowArgs.group then
listCell
:css('text-align', 'left')
:css('border-left-width', '2px')
:css('border-left-style', 'solid')
else
if haveSubgroups(args) then
listCell
:attr('colspan', 2)
end
end
if not args.groupwidth then
listCell:css('width', '100%')
end
local listText = rowArgs.list
local oddEven = ODD_EVEN_MARKER
if listText:sub(1, 12) == '</div><table' then
-- Assume list text is for a subgroup navbox so no automatic striping for this row.
oddEven = listText:find('<th[^>]*"navbox%-title"') and RESTART_MARKER or 'odd'
end
listCell
:css('padding', '0px')
:cssText(args.liststyle)
:cssText(rowArgs.liststyle)
:addClass('navbox-list')
:addClass('navbox-' .. oddEven)
:addClass(args.listclass)
:tag('div')
:css('padding', rowArgs.listpadding or args.listpadding or '0em 0.25em')
:wikitext(addNewline(listText))
if index == 1 and args.image then
row
:tag('td')
:addClass('navbox-image')
:addClass(args.imageclass)
:css('width', '1px')
:css('padding', '0px 0px 0px 7px')
:cssText(args.imagestyle)
:attr('rowspan', rowspan)
:tag('div')
:wikitext(addNewline(args.image))
end
end
--
-- Tracking categories
--
local function needsChangetoSubgroups(args)
for i = 1, 23 do
if (checkElAliases(args, 'group', i)) and not (checkElAliases(args, 'list', i)) then
return true
end
end
return false
end
local function needsHorizontalLists(args)
if args.border == 'subgroup' or args.tracking == 'no' then
return false
end
local listClasses = {
['plainlist'] = true, ['hlist'] = true, ['hlist hnum'] = true,
['hlist hwrap'] = true, ['hlist vcard'] = true, ['vcard hlist'] = true,
['hlist vevent'] = true, ['hlist hlist-items-nowrap'] = true, ['hlist-items-nowrap'] = true,
}
return not (listClasses[args.listclass] or listClasses[args.bodyclass])
end
-- local function hasBackgroundColors()
-- return mw.ustring.match(titlestyle or '','background') or mw.ustring.match(groupstyle or '','background') or mw.ustring.match(basestyle or '','background')
-- end
local function isIllegible(args)
if not styleratio then
styleratio = require('Module:Color contrast')._styleratio
end
for key, style in pairs(args) do
if tostring(key):match("style$") or tostring(key):match("^стиль") then
if styleratio{mw.text.unstripNoWiki(style)} < 4.5 then
return true
end
end
end
return false
end
local function getTrackingCategories(args)
local cats = {}
if needsChangetoSubgroups(args) then table.insert(cats, 'Навигационные шаблоны с ошибочным использованием заголовков') end
if needsHorizontalLists(args) then table.insert(cats, 'Навигационные шаблоны без горизонтальных списков') end
if isIllegible(args) then table.insert(cats, 'Потенциально нечитаемые навигационные шаблоны') end
return cats
end
local function renderTrackingCategories(builder, args)
local title = mw.title.getCurrentTitle()
if title.namespace ~= 10 then return end -- not in template space
local subpage = title.subpageText
if subpage == 'doc' or subpage == 'песочница' or subpage == 'тесты' then return end
for i, cat in ipairs(getTrackingCategories(args)) do
builder:wikitext('[[Категория:' .. cat .. ']]')
end
end
--
-- Main navbox tables
--
local function renderMainTable(args, listnums)
local tbl = mw.html.create('table')
:addClass('nowraplinks')
:addClass(args.bodyclass)
if args.title and (args.state ~= 'plain' and args.state ~= 'off') then
tbl
:addClass('collapsible')
:addClass(args.state or 'autocollapse')
end
tbl:css('border-spacing', 0)
if args.border == 'subgroup' or args.border == 'none' then
tbl
:addClass('navbox-subgroup')
:cssText(args.bodystyle)
else -- regular navbox - bodystyle and style will be applied to the wrapper table
tbl
:addClass('navbox-inner')
:css('background', 'transparent')
:css('color', 'inherit')
end
tbl:cssText(args.innerstyle)
renderTitleRow(tbl, args)
renderAboveRow(tbl, args)
for i, listnum in ipairs(listnums) do
local rowArgs = {
group = checkElAliases(args, 'group', listnum),
list = checkElAliases(args, 'list', listnum),
groupstyle = checkElAliases(args, 'groupstyle', listnum),
liststyle = checkElAliases(args, 'liststyle', listnum),
listpadding = checkElAliases(args, 'listpadding', listnum)
}
renderListRow(tbl, args, i, #listnums, rowArgs)
end
renderBelowRow(tbl, args)
return tbl
end
-- Read the arguments in the order they'll be output in, to make references number in the right order.
local function readInTheRightOrder(args, groupAliases, listAliases)
local _
_ = checkAliases(args, commonAliases.title)
_ = checkAliases(args, commonAliases.above)
for i = 1, 23 do
_ = checkAliases(args, groupAliases, i)
_ = checkAliases(args, listAliases, i)
end
_ = checkAliases(args, commonAliases.below)
end
function p._navbox(args)
if not yesno then
yesno = require('Module:Yesno')
end
local listnums = {}
for k, v in pairs(args) do
local listnum = ('' .. k):match('^list(%d+)$') or ('' .. k):match('^список(%d+)$')
if listnum then table.insert(listnums, tonumber(listnum)) end
end
table.sort(listnums)
args.border = mw.text.trim(args.border or args[1] or '')
if args.border == 'child' then
args.border = 'subgroup'
end
for argname, aliasesList in pairs(commonAliases) do
args[argname] = checkAliases(args, aliasesList)
end
for argname, aliasesList in pairs(standardAliases) do
args[argname] = checkAliases(args, aliasesList)
end
args.navigation = yesno(args.navigation, '')
-- render the main body of the navbox
local tbl = renderMainTable(args, listnums)
-- render the appropriate wrapper around the navbox, depending on the border param
local res = mw.html.create()
if args.border == 'none' then
local nav = res:tag('div')
:attr('role', 'navigation')
:node(tbl)
if args.title then
nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title))
else
nav:attr('aria-label', 'Навигационный шаблон')
end
if args.name and args.name ~= '-' then
nav:attr('data-name', args.name)
end
if args.navigation == true then
nav:attr('data-navboxnavigation', '1')
elseif args.navigation == false then
nav:attr('data-navboxnavigation', '0')
end
elseif args.border == 'subgroup' then
-- We assume that this navbox is being rendered in a list cell of a parent navbox, and is
-- therefore inside a div with padding:0em 0.25em. We start with a </div> to avoid the
-- padding being applied, and at the end add a <div> to balance out the parent's </div>
res
:wikitext('</div>') -- XXX: hack due to lack of unclosed support in mw.html.
:node(tbl)
:wikitext('<div>') -- XXX: hack due to lack of unclosed support in mw.html.
else
local nav = res:tag('div')
:attr('role', 'navigation')
:addClass('navbox')
:cssText(args.bodystyle)
:css('padding', '3px')
:node(tbl)
if args.title then
nav:attr('aria-labelledby', mw.uri.anchorEncode(args.title))
else
nav:attr('aria-label', 'Навигационный шаблон')
end
if args.name and args.name ~= '-' then
nav:attr('data-name', args.name)
end
if args.navigation == true then
nav:attr('data-navboxnavigation', '1')
elseif args.navigation == false then
nav:attr('data-navboxnavigation', '0')
end
end
renderTrackingCategories(res, args)
return striped(tostring(res), args)
end
function p.navbox(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
if not yesno then
yesno = require('Module:Yesno')
end
args = getArgs(frame, {wrappers = {'Шаблон:Навигационная таблица', 'Шаблон:Подгруппы навигационной таблицы'}})
if frame.args.border then
-- This allows Template:Navbox_subgroup to use {{#invoke:Navbox|navbox|border=...}}.
args.border = frame.args.border
end
readInTheRightOrder(args, standardElementAliases.group, standardElementAliases.list)
return p._navbox(args)
end
function p.navboxWithCollapsibleGroups(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
local args = getArgs(frame, {wrappers = {'Шаблон:Навигационная таблица с блоками'}})
readInTheRightOrder(args, groupsChildAliases.title, groupsChildAliases.list1)
local parent = {}
for argname, aliasesList in pairs(commonAliases) do
parent[argname] = checkAliases(args, aliasesList)
end
for argname, aliasesList in pairs(groupsParentAliases) do
parent[argname] = checkAliases(args, aliasesList)
end
for i = 1, 20 do
local child = {}
for argname, aliasesList in pairs(groupsChildAliases) do
child[argname] = checkAliases(args, aliasesList, i)
end
child.color = child.color and string.format('background:%s;', child.color) or ''
child.border = 'child'
child.navbar = 'plain'
if parent.selected and parent.selected == child.groupname then
child.state = 'uncollapsed'
end
child.state = child.state or 'collapsed'
child.basestyle = concatStyles{parent.basestyle, parent.secttitlestyle, child.secttitlestyle}
child.titlestyle = concatStyles{parent._groupstyle, child.groupstyle, child.color}
child.liststyle = concatStyles{parent._liststyle, child.liststyle}
child.lispadding = parent._listpadding
if child.title then
parent['list' .. i] = p._navbox(child)
else
parent['list' .. i] = child.list1
end
end
return p._navbox(parent)
end
return p
143824f957f6bf9e642eed17ea875caf2dd8d277
Модуль:Yesno
828
127
663
574
2024-08-16T16:58:46Z
DuOfOrl
5
Scribunto
text/plain
-- Function allowing for consistent treatment of boolean-like wikitext input.
-- It works similarly to the template {{yesno}}.
return function (val, default)
-- If your wiki uses non-ascii characters for any of "yes", "no", etc., you
-- should replace "val:lower()" with "mw.ustring.lower(val)" in the
-- following line.
val = type(val) == 'string' and val:lower() or val
if val == nil then
return nil
elseif val == true
or val == 'yes'
or val == 'y'
or val == 'true'
or val == 't'
or val == 'да'
or val == 'д'
or val == '+'
or tonumber(val) == 1
then
return true
elseif val == false
or val == 'no'
or val == 'n'
or val == 'false'
or val == 'f'
or val == 'нет'
or val == 'н'
or val == '-'
or tonumber(val) == 0
then
return false
else
return default
end
end
2aa6facc3ee47eb7582d828363d3c1ddc64593d2
Шаблон:Карточка/styles.css
10
252
664
2024-08-16T17:18:58Z
DuOfOrl
5
Новая страница: «/* Вынесено из [[MediaWiki:Common.css]] и [[MediaWiki:Mobile.css]] */ .infobox-table, .infobox-tablebox { padding: 0; } .infobox-inner-table, .infobox-table > table, .infobox-tablebox > table { width: 100%; display: table; margin: 0; background: transparent; } .infobox-tablebox > table { border: 1px solid var(--border-color-base, #a2a9b1); border-collapse: separate; } /* Встраиваемая карточка */ .infobox-child { width:...»
sanitized-css
text/css
/* Вынесено из [[MediaWiki:Common.css]] и [[MediaWiki:Mobile.css]] */
.infobox-table,
.infobox-tablebox {
padding: 0;
}
.infobox-inner-table,
.infobox-table > table,
.infobox-tablebox > table {
width: 100%;
display: table;
margin: 0;
background: transparent;
}
.infobox-tablebox > table {
border: 1px solid var(--border-color-base, #a2a9b1);
border-collapse: separate;
}
/* Встраиваемая карточка */
.infobox-child {
width: 100%;
margin: 0;
padding: 0;
border: none;
font-size: 100%;
}
body.skin-minerva table.infobox-child {
width: 100% !important;
margin: 0 !important;
padding: 0;
border: none;
font-size: 100%;
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
b01ab8a24cfa42c6b091b6ebe1f33dcaf345a6f8
Шаблон:Doc/styles.css
10
173
665
605
2024-08-26T15:40:10Z
176.59.55.152
0
sanitized-css
text/css
.ts-doc-doc {
background-color: var(--background-color-progressive-subtle, #eaf3ff);
border: 1px solid var(--border-color-content-added, #afb6e9);
clear: both;
margin-top: 1em;
}
/* Ctrl+F ":target" in [[MediaWiki:Common.css]] */
.ts-doc-doc sup.reference:target,
.ts-doc-doc ol.references li:target,
.ts-doc-doc .highlight-target:target,
.ts-doc-doc cite:target,
.ts-doc-doc span.citation:target {
background: var(--ruwiki-background-color-blue200, #cfe3ff);
}
.ts-doc-header {
align-items: center;
background: var(--ruwiki-background-color-blue200, #cfe3ff);
display: flex;
flex-wrap: wrap;
padding: .642857em 1em .5em;
overflow: hidden;
}
.ts-doc-header .ts-tlinks-tlinks {
margin-left: auto;
}
.ts-doc-content {
padding: .214286em 1em;
}
.ts-doc-content:after {
content: '';
clear: both;
display: block;
}
.ts-doc-heading {
display: inline-block;
padding-left: 2em;
background: url(//upload.wikimedia.org/wikipedia/commons/c/ca/OOjs_UI_icon_info.svg) center left no-repeat;
background-size: contain;
font-size: small;
min-height: 1.75em;
font-weight: 600;
letter-spacing: 0.1em;
text-transform: uppercase;
}
@media screen {
html.skin-theme-clientpref-night .ts-doc-heading {
background-image: url(//upload.wikimedia.org/wikipedia/commons/c/c0/OOjs_UI_icon_info-invert.svg);
}
}
@media screen and (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os .ts-doc-heading {
background-image: url(//upload.wikimedia.org/wikipedia/commons/c/c0/OOjs_UI_icon_info-invert.svg);
}
}
.ts-doc-content > *:first-child,
.ts-doc-footer > *:first-child {
margin-top: .5em;
}
.ts-doc-content > *:last-child,
.ts-doc-footer > *:last-child {
margin-bottom: .5em;
}
.ts-doc-footer {
background-color: var(--background-color-progressive-subtle, #eaf3ff);
border: 1px solid var(--border-color-content-added, #afb6e9);
padding: .214286em 1em;
margin-top: .214286em;
margin-bottom: .214286em;
font-style: italic;
}
@media (max-width: 719px) {
.ts-doc-header {
display: block;
}
.ts-doc-header .ts-tlinks-tlinks {
float: none;
}
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
be8d912472a37a6051bee114da86f913839e7ca0
Шаблон:Карточка/импортёр
10
253
667
666
2024-08-26T15:44:22Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{ {{{|safesubst:}}}require subst
| <noinclude></noinclude>{{Карточка
{{subst:!}}{{subst:#if:{{{name|}}} |имя = {{{name}}}
{{subst:!}}}}{{subst:#if:{{{bodyclass|}}} |класс_тела = {{{bodyclass}}}
{{subst:!}}}}{{subst:#if:{{{bodystyle|}}} |стиль_тела = {{{bodystyle}}}
{{subst:!}}}}{{subst:#if:{{{title|}}} |вверху = {{{title}}}
{{subst:!}}}}{{subst:#if:{{{titleclass|}}} |класс_вверху = {{{titleclass}}}
{{subst:!}}}}{{subst:#if:{{{titlestyle|}}} |стиль_вверху = {{{titlestyle}}}
{{subst:!}}}}{{subst:#if:{{{above|}}} |вверху2 = {{{above}}}
{{subst:!}}}}{{subst:#if:{{{aboveclass|}}} |класс_вверху2 = {{{aboveclass}}}
{{subst:!}}}}{{subst:#if:{{{abovestyle|}}} |стиль_вверху2 = {{{abovestyle}}}
{{subst:!}}}}{{subst:#if:{{{image|}}} |изображение = {{{image}}}
{{subst:!}}}}{{subst:#if:{{{imageclass|}}} |класс_изображения = {{{imageclass}}}
{{subst:!}}}}{{subst:#if:{{{imagestyle|}}} |стиль_изображения = {{{imagestyle}}}
{{subst:!}}}}{{subst:#if:{{{caption|}}} |подпись = {{{caption}}}
{{subst:!}}}}{{subst:#if:{{{captionstyle|}}} |стиль_подписи = {{{captionstyle}}}
{{subst:!}}}}{{subst:#if:{{{headerstyle|}}} |стиль_заголовков = {{{headerstyle}}}
{{subst:!}}}}{{subst:#if:{{{labelstyle|}}} |стиль_меток = {{{labelstyle}}}
{{subst:!}}}}{{subst:#if:{{{datastyle|}}} |стиль_текста = {{{datastyle}}}
{{subst:!}}}}{{subst:#if:{{{header1|}}} |заголовок1 = {{{header1}}}
{{subst:!}}}}{{subst:#if:{{{label1|}}} |метка1 = {{{label1}}}
{{subst:!}}}}{{subst:#if:{{{data1|}}} |текст1 = {{{data1}}}
{{subst:!}}}}{{subst:#if:{{{class1|}}} |класс1 = {{{class1}}}
{{subst:!}}}}{{subst:#if:{{{header2|}}} |заголовок2 = {{{header2}}}
{{subst:!}}}}{{subst:#if:{{{label2|}}} |метка2 = {{{label2}}}
{{subst:!}}}}{{subst:#if:{{{data2|}}} |текст2 = {{{data2}}}
{{subst:!}}}}{{subst:#if:{{{class2|}}} |класс2 = {{{class2}}}
{{subst:!}}}}{{subst:#if:{{{header3|}}} |заголовок3 = {{{header3}}}
{{subst:!}}}}{{subst:#if:{{{label3|}}} |метка3 = {{{label3}}}
{{subst:!}}}}{{subst:#if:{{{data3|}}} |текст3 = {{{data3}}}
{{subst:!}}}}{{subst:#if:{{{class3|}}} |класс3 = {{{class3}}}
{{subst:!}}}}{{subst:#if:{{{header4|}}} |заголовок4 = {{{header4}}}
{{subst:!}}}}{{subst:#if:{{{label4|}}} |метка4 = {{{label4}}}
{{subst:!}}}}{{subst:#if:{{{data4|}}} |текст4 = {{{data4}}}
{{subst:!}}}}{{subst:#if:{{{class4|}}} |класс4 = {{{class4}}}
{{subst:!}}}}{{subst:#if:{{{header5|}}} |заголовок5 = {{{header5}}}
{{subst:!}}}}{{subst:#if:{{{label5|}}} |метка5 = {{{label5}}}
{{subst:!}}}}{{subst:#if:{{{data5|}}} |текст5 = {{{data5}}}
{{subst:!}}}}{{subst:#if:{{{class5|}}} |класс5 = {{{class5}}}
{{subst:!}}}}{{subst:#if:{{{header6|}}} |заголовок6 = {{{header6}}}
{{subst:!}}}}{{subst:#if:{{{label6|}}} |метка6 = {{{label6}}}
{{subst:!}}}}{{subst:#if:{{{data6|}}} |текст6 = {{{data6}}}
{{subst:!}}}}{{subst:#if:{{{class6|}}} |класс6 = {{{class6}}}
{{subst:!}}}}{{subst:#if:{{{header7|}}} |заголовок7 = {{{header7}}}
{{subst:!}}}}{{subst:#if:{{{label7|}}} |метка7 = {{{label7}}}
{{subst:!}}}}{{subst:#if:{{{data7|}}} |текст7 = {{{data7}}}
{{subst:!}}}}{{subst:#if:{{{class7|}}} |класс7 = {{{class7}}}
{{subst:!}}}}{{subst:#if:{{{header8|}}} |заголовок8 = {{{header8}}}
{{subst:!}}}}{{subst:#if:{{{label8|}}} |метка8 = {{{label8}}}
{{subst:!}}}}{{subst:#if:{{{data8|}}} |текст8 = {{{data8}}}
{{subst:!}}}}{{subst:#if:{{{class8|}}} |класс8 = {{{class8}}}
{{subst:!}}}}{{subst:#if:{{{header9|}}} |заголовок9 = {{{header9}}}
{{subst:!}}}}{{subst:#if:{{{label9|}}} |метка9 = {{{label9}}}
{{subst:!}}}}{{subst:#if:{{{data9|}}} |текст9 = {{{data9}}}
{{subst:!}}}}{{subst:#if:{{{class9|}}} |класс9 = {{{class9}}}
{{subst:!}}}}{{subst:#if:{{{header10|}}} |заголовок10 = {{{header10}}}
{{subst:!}}}}{{subst:#if:{{{label10|}}} |метка10 = {{{label10}}}
{{subst:!}}}}{{subst:#if:{{{data10|}}} |текст10 = {{{data10}}}
{{subst:!}}}}{{subst:#if:{{{class10|}}} |класс10 = {{{class10}}}
{{subst:!}}}}{{subst:#if:{{{header11|}}} |заголовок11 = {{{header11}}}
{{subst:!}}}}{{subst:#if:{{{label11|}}} |метка11 = {{{label11}}}
{{subst:!}}}}{{subst:#if:{{{data11|}}} |текст11 = {{{data11}}}
{{subst:!}}}}{{subst:#if:{{{class11|}}} |класс11 = {{{class11}}}
{{subst:!}}}}{{subst:#if:{{{header12|}}} |заголовок12 = {{{header12}}}
{{subst:!}}}}{{subst:#if:{{{label12|}}} |метка12 = {{{label12}}}
{{subst:!}}}}{{subst:#if:{{{data12|}}} |текст12 = {{{data12}}}
{{subst:!}}}}{{subst:#if:{{{class12|}}} |класс12 = {{{class12}}}
{{subst:!}}}}{{subst:#if:{{{header13|}}} |заголовок13 = {{{header13}}}
{{subst:!}}}}{{subst:#if:{{{label13|}}} |метка13 = {{{label13}}}
{{subst:!}}}}{{subst:#if:{{{data13|}}} |текст13 = {{{data13}}}
{{subst:!}}}}{{subst:#if:{{{class13|}}} |класс13 = {{{class13}}}
{{subst:!}}}}{{subst:#if:{{{header14|}}} |заголовок14 = {{{header14}}}
{{subst:!}}}}{{subst:#if:{{{label14|}}} |метка14 = {{{label14}}}
{{subst:!}}}}{{subst:#if:{{{data14|}}} |текст14 = {{{data14}}}
{{subst:!}}}}{{subst:#if:{{{class14|}}} |класс14 = {{{class14}}}
{{subst:!}}}}{{subst:#if:{{{header15|}}} |заголовок15 = {{{header15}}}
{{subst:!}}}}{{subst:#if:{{{label15|}}} |метка15 = {{{label15}}}
{{subst:!}}}}{{subst:#if:{{{data15|}}} |текст15 = {{{data15}}}
{{subst:!}}}}{{subst:#if:{{{class15|}}} |класс15 = {{{class15}}}
{{subst:!}}}}{{subst:#if:{{{header16|}}} |заголовок16 = {{{header16}}}
{{subst:!}}}}{{subst:#if:{{{label16|}}} |метка16 = {{{label16}}}
{{subst:!}}}}{{subst:#if:{{{data16|}}} |текст16 = {{{data16}}}
{{subst:!}}}}{{subst:#if:{{{class16|}}} |класс16 = {{{class16}}}
{{subst:!}}}}{{subst:#if:{{{header17|}}} |заголовок17 = {{{header17}}}
{{subst:!}}}}{{subst:#if:{{{label17|}}} |метка17 = {{{label17}}}
{{subst:!}}}}{{subst:#if:{{{data17|}}} |текст17 = {{{data17}}}
{{subst:!}}}}{{subst:#if:{{{class17|}}} |класс17 = {{{class17}}}
{{subst:!}}}}{{subst:#if:{{{header18|}}} |заголовок18 = {{{header18}}}
{{subst:!}}}}{{subst:#if:{{{label18|}}} |метка18 = {{{label18}}}
{{subst:!}}}}{{subst:#if:{{{data18|}}} |текст18 = {{{data18}}}
{{subst:!}}}}{{subst:#if:{{{class18|}}} |класс18 = {{{class18}}}
{{subst:!}}}}{{subst:#if:{{{header19|}}} |заголовок19 = {{{header19}}}
{{subst:!}}}}{{subst:#if:{{{label19|}}} |метка19 = {{{label19}}}
{{subst:!}}}}{{subst:#if:{{{data19|}}} |текст19 = {{{data19}}}
{{subst:!}}}}{{subst:#if:{{{class19|}}} |класс19 = {{{class19}}}
{{subst:!}}}}{{subst:#if:{{{header20|}}} |заголовок20 = {{{header20}}}
{{subst:!}}}}{{subst:#if:{{{label20|}}} |метка20 = {{{label20}}}
{{subst:!}}}}{{subst:#if:{{{data20|}}} |текст20 = {{{data20}}}
{{subst:!}}}}{{subst:#if:{{{class20|}}} |класс20 = {{{class20}}}
{{subst:!}}}}{{subst:#if:{{{header21|}}} |заголовок21 = {{{header21}}}
{{subst:!}}}}{{subst:#if:{{{label21|}}} |метка21 = {{{label21}}}
{{subst:!}}}}{{subst:#if:{{{data21|}}} |текст21 = {{{data21}}}
{{subst:!}}}}{{subst:#if:{{{class21|}}} |класс21 = {{{class21}}}
{{subst:!}}}}{{subst:#if:{{{header22|}}} |заголовок22 = {{{header22}}}
{{subst:!}}}}{{subst:#if:{{{label22|}}} |метка22 = {{{label22}}}
{{subst:!}}}}{{subst:#if:{{{data22|}}} |текст22 = {{{data22}}}
{{subst:!}}}}{{subst:#if:{{{class22|}}} |класс22 = {{{class22}}}
{{subst:!}}}}{{subst:#if:{{{header23|}}} |заголовок23 = {{{header23}}}
{{subst:!}}}}{{subst:#if:{{{label23|}}} |метка23 = {{{label23}}}
{{subst:!}}}}{{subst:#if:{{{data23|}}} |текст23 = {{{data23}}}
{{subst:!}}}}{{subst:#if:{{{class23|}}} |класс23 = {{{class23}}}
{{subst:!}}}}{{subst:#if:{{{header24|}}} |заголовок24 = {{{header24}}}
{{subst:!}}}}{{subst:#if:{{{label24|}}} |метка24 = {{{label24}}}
{{subst:!}}}}{{subst:#if:{{{data24|}}} |текст24 = {{{data24}}}
{{subst:!}}}}{{subst:#if:{{{class24|}}} |класс24 = {{{class24}}}
{{subst:!}}}}{{subst:#if:{{{header25|}}} |заголовок25 = {{{header25}}}
{{subst:!}}}}{{subst:#if:{{{label25|}}} |метка25 = {{{label25}}}
{{subst:!}}}}{{subst:#if:{{{data25|}}} |текст25 = {{{data25}}}
{{subst:!}}}}{{subst:#if:{{{class25|}}} |класс25 = {{{class25}}}
{{subst:!}}}}{{subst:#if:{{{header26|}}} |заголовок26 = {{{header26}}}
{{subst:!}}}}{{subst:#if:{{{label26|}}} |метка26 = {{{label26}}}
{{subst:!}}}}{{subst:#if:{{{data26|}}} |текст26 = {{{data26}}}
{{subst:!}}}}{{subst:#if:{{{class26|}}} |класс26 = {{{class26}}}
{{subst:!}}}}{{subst:#if:{{{header27|}}} |заголовок27 = {{{header27}}}
{{subst:!}}}}{{subst:#if:{{{label27|}}} |метка27 = {{{label27}}}
{{subst:!}}}}{{subst:#if:{{{data27|}}} |текст27 = {{{data27}}}
{{subst:!}}}}{{subst:#if:{{{class27|}}} |класс27 = {{{class27}}}
{{subst:!}}}}{{subst:#if:{{{header28|}}} |заголовок28 = {{{header28}}}
{{subst:!}}}}{{subst:#if:{{{label28|}}} |метка28 = {{{label28}}}
{{subst:!}}}}{{subst:#if:{{{data28|}}} |текст28 = {{{data28}}}
{{subst:!}}}}{{subst:#if:{{{class28|}}} |класс28 = {{{class28}}}
{{subst:!}}}}{{subst:#if:{{{header29|}}} |заголовок29 = {{{header29}}}
{{subst:!}}}}{{subst:#if:{{{label29|}}} |метка29 = {{{label29}}}
{{subst:!}}}}{{subst:#if:{{{data29|}}} |текст29 = {{{data29}}}
{{subst:!}}}}{{subst:#if:{{{class29|}}} |класс29 = {{{class29}}}
{{subst:!}}}}{{subst:#if:{{{header30|}}} |заголовок30 = {{{header30}}}
{{subst:!}}}}{{subst:#if:{{{label30|}}} |метка30 = {{{label30}}}
{{subst:!}}}}{{subst:#if:{{{data30|}}} |текст30 = {{{data30}}}
{{subst:!}}}}{{subst:#if:{{{class30|}}} |класс30 = {{{class30}}}
{{subst:!}}}}{{subst:#if:{{{header31|}}} |заголовок31 = {{{header31}}}
{{subst:!}}}}{{subst:#if:{{{label31|}}} |метка31 = {{{label31}}}
{{subst:!}}}}{{subst:#if:{{{data31|}}} |текст31 = {{{data31}}}
{{subst:!}}}}{{subst:#if:{{{class31|}}} |класс31 = {{{class31}}}
{{subst:!}}}}{{subst:#if:{{{header32|}}} |заголовок32 = {{{header32}}}
{{subst:!}}}}{{subst:#if:{{{label32|}}} |метка32 = {{{label32}}}
{{subst:!}}}}{{subst:#if:{{{data32|}}} |текст32 = {{{data32}}}
{{subst:!}}}}{{subst:#if:{{{class32|}}} |класс32 = {{{class32}}}
{{subst:!}}}}{{subst:#if:{{{header33|}}} |заголовок33 = {{{header33}}}
{{subst:!}}}}{{subst:#if:{{{label33|}}} |метка33 = {{{label33}}}
{{subst:!}}}}{{subst:#if:{{{data33|}}} |текст33 = {{{data33}}}
{{subst:!}}}}{{subst:#if:{{{class33|}}} |класс33 = {{{class33}}}
{{subst:!}}}}{{subst:#if:{{{header34|}}} |заголовок34 = {{{header34}}}
{{subst:!}}}}{{subst:#if:{{{label34|}}} |метка34 = {{{label34}}}
{{subst:!}}}}{{subst:#if:{{{data34|}}} |текст34 = {{{data34}}}
{{subst:!}}}}{{subst:#if:{{{class34|}}} |класс34 = {{{class34}}}
{{subst:!}}}}{{subst:#if:{{{header35|}}} |заголовок35 = {{{header35}}}
{{subst:!}}}}{{subst:#if:{{{label35|}}} |метка35 = {{{label35}}}
{{subst:!}}}}{{subst:#if:{{{data35|}}} |текст35 = {{{data35}}}
{{subst:!}}}}{{subst:#if:{{{class35|}}} |класс35 = {{{class35}}}
{{subst:!}}}}{{subst:#if:{{{header36|}}} |заголовок36 = {{{header36}}}
{{subst:!}}}}{{subst:#if:{{{label36|}}} |метка36 = {{{label36}}}
{{subst:!}}}}{{subst:#if:{{{data36|}}} |текст36 = {{{data36}}}
{{subst:!}}}}{{subst:#if:{{{class36|}}} |класс36 = {{{class36}}}
{{subst:!}}}}{{subst:#if:{{{header37|}}} |заголовок37 = {{{header37}}}
{{subst:!}}}}{{subst:#if:{{{label37|}}} |метка37 = {{{label37}}}
{{subst:!}}}}{{subst:#if:{{{data37|}}} |текст37 = {{{data37}}}
{{subst:!}}}}{{subst:#if:{{{class37|}}} |класс37 = {{{class37}}}
{{subst:!}}}}{{subst:#if:{{{header38|}}} |заголовок38 = {{{header38}}}
{{subst:!}}}}{{subst:#if:{{{label38|}}} |метка38 = {{{label38}}}
{{subst:!}}}}{{subst:#if:{{{data38|}}} |текст38 = {{{data38}}}
{{subst:!}}}}{{subst:#if:{{{class38|}}} |класс38 = {{{class38}}}
{{subst:!}}}}{{subst:#if:{{{header39|}}} |заголовок39 = {{{header39}}}
{{subst:!}}}}{{subst:#if:{{{label39|}}} |метка39 = {{{label39}}}
{{subst:!}}}}{{subst:#if:{{{data39|}}} |текст39 = {{{data39}}}
{{subst:!}}}}{{subst:#if:{{{class39|}}} |класс39 = {{{class39}}}
{{subst:!}}}}{{subst:#if:{{{header40|}}} |заголовок40 = {{{header40}}}
{{subst:!}}}}{{subst:#if:{{{label40|}}} |метка40 = {{{label40}}}
{{subst:!}}}}{{subst:#if:{{{data40|}}} |текст40 = {{{data40}}}
{{subst:!}}}}{{subst:#if:{{{class40|}}} |класс40 = {{{class40}}}
{{subst:!}}}}{{subst:#if:{{{header41|}}} |заголовок41 = {{{header41}}}
{{subst:!}}}}{{subst:#if:{{{label41|}}} |метка41 = {{{label41}}}
{{subst:!}}}}{{subst:#if:{{{data41|}}} |текст41 = {{{data41}}}
{{subst:!}}}}{{subst:#if:{{{class41|}}} |класс41 = {{{class41}}}
{{subst:!}}}}{{subst:#if:{{{header42|}}} |заголовок42 = {{{header42}}}
{{subst:!}}}}{{subst:#if:{{{label42|}}} |метка42 = {{{label42}}}
{{subst:!}}}}{{subst:#if:{{{data42|}}} |текст42 = {{{data42}}}
{{subst:!}}}}{{subst:#if:{{{class42|}}} |класс42 = {{{class42}}}
{{subst:!}}}}{{subst:#if:{{{header43|}}} |заголовок43 = {{{header43}}}
{{subst:!}}}}{{subst:#if:{{{label43|}}} |метка43 = {{{label43}}}
{{subst:!}}}}{{subst:#if:{{{data43|}}} |текст43 = {{{data43}}}
{{subst:!}}}}{{subst:#if:{{{class43|}}} |класс43 = {{{class43}}}
{{subst:!}}}}{{subst:#if:{{{header44|}}} |заголовок44 = {{{header44}}}
{{subst:!}}}}{{subst:#if:{{{label44|}}} |метка44 = {{{label44}}}
{{subst:!}}}}{{subst:#if:{{{data44|}}} |текст44 = {{{data44}}}
{{subst:!}}}}{{subst:#if:{{{class44|}}} |класс44 = {{{class44}}}
{{subst:!}}}}{{subst:#if:{{{header45|}}} |заголовок45 = {{{header45}}}
{{subst:!}}}}{{subst:#if:{{{label45|}}} |метка45 = {{{label45}}}
{{subst:!}}}}{{subst:#if:{{{data45|}}} |текст45 = {{{data45}}}
{{subst:!}}}}{{subst:#if:{{{class45|}}} |класс45 = {{{class45}}}
{{subst:!}}}}{{subst:#if:{{{header46|}}} |заголовок46 = {{{header46}}}
{{subst:!}}}}{{subst:#if:{{{label46|}}} |метка46 = {{{label46}}}
{{subst:!}}}}{{subst:#if:{{{data46|}}} |текст46 = {{{data46}}}
{{subst:!}}}}{{subst:#if:{{{class46|}}} |класс46 = {{{class46}}}
{{subst:!}}}}{{subst:#if:{{{header47|}}} |заголовок47 = {{{header47}}}
{{subst:!}}}}{{subst:#if:{{{label47|}}} |метка47 = {{{label47}}}
{{subst:!}}}}{{subst:#if:{{{data47|}}} |текст47 = {{{data47}}}
{{subst:!}}}}{{subst:#if:{{{class47|}}} |класс47 = {{{class47}}}
{{subst:!}}}}{{subst:#if:{{{header48|}}} |заголовок48 = {{{header48}}}
{{subst:!}}}}{{subst:#if:{{{label48|}}} |метка48 = {{{label48}}}
{{subst:!}}}}{{subst:#if:{{{data48|}}} |текст48 = {{{data48}}}
{{subst:!}}}}{{subst:#if:{{{class48|}}} |класс48 = {{{class48}}}
{{subst:!}}}}{{subst:#if:{{{header49|}}} |заголовок49 = {{{header49}}}
{{subst:!}}}}{{subst:#if:{{{label49|}}} |метка49 = {{{label49}}}
{{subst:!}}}}{{subst:#if:{{{data49|}}} |текст49 = {{{data49}}}
{{subst:!}}}}{{subst:#if:{{{class49|}}} |класс49 = {{{class49}}}
{{subst:!}}}}{{subst:#if:{{{header50|}}} |заголовок50 = {{{header50}}}
{{subst:!}}}}{{subst:#if:{{{label50|}}} |метка50 = {{{label50}}}
{{subst:!}}}}{{subst:#if:{{{data50|}}} |текст50 = {{{data50}}}
{{subst:!}}}}{{subst:#if:{{{class50|}}} |класс50 = {{{class50}}}
{{subst:!}}}}{{subst:#if:{{{header51|}}} |заголовок51 = {{{header51}}}
{{subst:!}}}}{{subst:#if:{{{label51|}}} |метка51 = {{{label51}}}
{{subst:!}}}}{{subst:#if:{{{data51|}}} |текст51 = {{{data51}}}
{{subst:!}}}}{{subst:#if:{{{class51|}}} |класс51 = {{{class51}}}
{{subst:!}}}}{{subst:#if:{{{header52|}}} |заголовок52 = {{{header52}}}
{{subst:!}}}}{{subst:#if:{{{label52|}}} |метка52 = {{{label52}}}
{{subst:!}}}}{{subst:#if:{{{data52|}}} |текст52 = {{{data52}}}
{{subst:!}}}}{{subst:#if:{{{class52|}}} |класс52 = {{{class52}}}
{{subst:!}}}}{{subst:#if:{{{header53|}}} |заголовок53 = {{{header53}}}
{{subst:!}}}}{{subst:#if:{{{label53|}}} |метка53 = {{{label53}}}
{{subst:!}}}}{{subst:#if:{{{data53|}}} |текст53 = {{{data53}}}
{{subst:!}}}}{{subst:#if:{{{class53|}}} |класс53 = {{{class53}}}
{{subst:!}}}}{{subst:#if:{{{header54|}}} |заголовок54 = {{{header54}}}
{{subst:!}}}}{{subst:#if:{{{label54|}}} |метка54 = {{{label54}}}
{{subst:!}}}}{{subst:#if:{{{data54|}}} |текст54 = {{{data54}}}
{{subst:!}}}}{{subst:#if:{{{class54|}}} |класс54 = {{{class54}}}
{{subst:!}}}}{{subst:#if:{{{header55|}}} |заголовок55 = {{{header55}}}
{{subst:!}}}}{{subst:#if:{{{label55|}}} |метка55 = {{{label55}}}
{{subst:!}}}}{{subst:#if:{{{data55|}}} |текст55 = {{{data55}}}
{{subst:!}}}}{{subst:#if:{{{class55|}}} |класс55 = {{{class55}}}
{{subst:!}}}}{{subst:#if:{{{header56|}}} |заголовок56 = {{{header56}}}
{{subst:!}}}}{{subst:#if:{{{label56|}}} |метка56 = {{{label56}}}
{{subst:!}}}}{{subst:#if:{{{data56|}}} |текст56 = {{{data56}}}
{{subst:!}}}}{{subst:#if:{{{class56|}}} |класс56 = {{{class56}}}
{{subst:!}}}}{{subst:#if:{{{header57|}}} |заголовок57 = {{{header57}}}
{{subst:!}}}}{{subst:#if:{{{label57|}}} |метка57 = {{{label57}}}
{{subst:!}}}}{{subst:#if:{{{data57|}}} |текст57 = {{{data57}}}
{{subst:!}}}}{{subst:#if:{{{class57|}}} |класс57 = {{{class57}}}
{{subst:!}}}}{{subst:#if:{{{header58|}}} |заголовок58 = {{{header58}}}
{{subst:!}}}}{{subst:#if:{{{label58|}}} |метка58 = {{{label58}}}
{{subst:!}}}}{{subst:#if:{{{data58|}}} |текст58 = {{{data58}}}
{{subst:!}}}}{{subst:#if:{{{class58|}}} |класс58 = {{{class58}}}
{{subst:!}}}}{{subst:#if:{{{header59|}}} |заголовок59 = {{{header59}}}
{{subst:!}}}}{{subst:#if:{{{label59|}}} |метка59 = {{{label59}}}
{{subst:!}}}}{{subst:#if:{{{data59|}}} |текст59 = {{{data59}}}
{{subst:!}}}}{{subst:#if:{{{class59|}}} |класс59 = {{{class59}}}
{{subst:!}}}}{{subst:#if:{{{header60|}}} |заголовок60 = {{{header60}}}
{{subst:!}}}}{{subst:#if:{{{label60|}}} |метка60 = {{{label60}}}
{{subst:!}}}}{{subst:#if:{{{data60|}}} |текст60 = {{{data60}}}
{{subst:!}}}}{{subst:#if:{{{class60|}}} |класс60 = {{{class60}}}
{{subst:!}}}}{{subst:#if:{{{header61|}}} |заголовок61 = {{{header61}}}
{{subst:!}}}}{{subst:#if:{{{label61|}}} |метка61 = {{{label61}}}
{{subst:!}}}}{{subst:#if:{{{data61|}}} |текст61 = {{{data61}}}
{{subst:!}}}}{{subst:#if:{{{class61|}}} |класс61 = {{{class61}}}
{{subst:!}}}}{{subst:#if:{{{header62|}}} |заголовок62 = {{{header62}}}
{{subst:!}}}}{{subst:#if:{{{label62|}}} |метка62 = {{{label62}}}
{{subst:!}}}}{{subst:#if:{{{data62|}}} |текст62 = {{{data62}}}
{{subst:!}}}}{{subst:#if:{{{class62|}}} |класс62 = {{{class62}}}
{{subst:!}}}}{{subst:#if:{{{header63|}}} |заголовок63 = {{{header63}}}
{{subst:!}}}}{{subst:#if:{{{label63|}}} |метка63 = {{{label63}}}
{{subst:!}}}}{{subst:#if:{{{data63|}}} |текст63 = {{{data63}}}
{{subst:!}}}}{{subst:#if:{{{class63|}}} |класс63 = {{{class63}}}
{{subst:!}}}}{{subst:#if:{{{header64|}}} |заголовок64 = {{{header64}}}
{{subst:!}}}}{{subst:#if:{{{label64|}}} |метка64 = {{{label64}}}
{{subst:!}}}}{{subst:#if:{{{data64|}}} |текст64 = {{{data64}}}
{{subst:!}}}}{{subst:#if:{{{class64|}}} |класс64 = {{{class64}}}
{{subst:!}}}}{{subst:#if:{{{header65|}}} |заголовок65 = {{{header65}}}
{{subst:!}}}}{{subst:#if:{{{label65|}}} |метка65 = {{{label65}}}
{{subst:!}}}}{{subst:#if:{{{data65|}}} |текст65 = {{{data65}}}
{{subst:!}}}}{{subst:#if:{{{class65|}}} |класс65 = {{{class65}}}
{{subst:!}}}}{{subst:#if:{{{header66|}}} |заголовок66 = {{{header66}}}
{{subst:!}}}}{{subst:#if:{{{label66|}}} |метка66 = {{{label66}}}
{{subst:!}}}}{{subst:#if:{{{data66|}}} |текст66 = {{{data66}}}
{{subst:!}}}}{{subst:#if:{{{class66|}}} |класс66 = {{{class66}}}
{{subst:!}}}}{{subst:#if:{{{header67|}}} |заголовок67 = {{{header67}}}
{{subst:!}}}}{{subst:#if:{{{label67|}}} |метка67 = {{{label67}}}
{{subst:!}}}}{{subst:#if:{{{data67|}}} |текст67 = {{{data67}}}
{{subst:!}}}}{{subst:#if:{{{class67|}}} |класс67 = {{{class67}}}
{{subst:!}}}}{{subst:#if:{{{header68|}}} |заголовок68 = {{{header68}}}
{{subst:!}}}}{{subst:#if:{{{label68|}}} |метка68 = {{{label68}}}
{{subst:!}}}}{{subst:#if:{{{data68|}}} |текст68 = {{{data68}}}
{{subst:!}}}}{{subst:#if:{{{class68|}}} |класс68 = {{{class68}}}
{{subst:!}}}}{{subst:#if:{{{header69|}}} |заголовок69 = {{{header69}}}
{{subst:!}}}}{{subst:#if:{{{label69|}}} |метка69 = {{{label69}}}
{{subst:!}}}}{{subst:#if:{{{data69|}}} |текст69 = {{{data69}}}
{{subst:!}}}}{{subst:#if:{{{class69|}}} |класс69 = {{{class69}}}
{{subst:!}}}}{{subst:#if:{{{header70|}}} |заголовок70 = {{{header70}}}
{{subst:!}}}}{{subst:#if:{{{label70|}}} |метка70 = {{{label70}}}
{{subst:!}}}}{{subst:#if:{{{data70|}}} |текст70 = {{{data70}}}
{{subst:!}}}}{{subst:#if:{{{class70|}}} |класс70 = {{{class70}}}
{{subst:!}}}}{{subst:#if:{{{header71|}}} |заголовок71 = {{{header71}}}
{{subst:!}}}}{{subst:#if:{{{label71|}}} |метка71 = {{{label71}}}
{{subst:!}}}}{{subst:#if:{{{data71|}}} |текст71 = {{{data71}}}
{{subst:!}}}}{{subst:#if:{{{class71|}}} |класс71 = {{{class71}}}
{{subst:!}}}}{{subst:#if:{{{header72|}}} |заголовок72 = {{{header72}}}
{{subst:!}}}}{{subst:#if:{{{label72|}}} |метка72 = {{{label72}}}
{{subst:!}}}}{{subst:#if:{{{data72|}}} |текст72 = {{{data72}}}
{{subst:!}}}}{{subst:#if:{{{class72|}}} |класс72 = {{{class72}}}
{{subst:!}}}}{{subst:#if:{{{header73|}}} |заголовок73 = {{{header73}}}
{{subst:!}}}}{{subst:#if:{{{label73|}}} |метка73 = {{{label73}}}
{{subst:!}}}}{{subst:#if:{{{data73|}}} |текст73 = {{{data73}}}
{{subst:!}}}}{{subst:#if:{{{class73|}}} |класс73 = {{{class73}}}
{{subst:!}}}}{{subst:#if:{{{header74|}}} |заголовок74 = {{{header74}}}
{{subst:!}}}}{{subst:#if:{{{label74|}}} |метка74 = {{{label74}}}
{{subst:!}}}}{{subst:#if:{{{data74|}}} |текст74 = {{{data74}}}
{{subst:!}}}}{{subst:#if:{{{class74|}}} |класс74 = {{{class74}}}
{{subst:!}}}}{{subst:#if:{{{header75|}}} |заголовок75 = {{{header75}}}
{{subst:!}}}}{{subst:#if:{{{label75|}}} |метка75 = {{{label75}}}
{{subst:!}}}}{{subst:#if:{{{data75|}}} |текст75 = {{{data75}}}
{{subst:!}}}}{{subst:#if:{{{class75|}}} |класс75 = {{{class75}}}
{{subst:!}}}}{{subst:#if:{{{header76|}}} |заголовок76 = {{{header76}}}
{{subst:!}}}}{{subst:#if:{{{label76|}}} |метка76 = {{{label76}}}
{{subst:!}}}}{{subst:#if:{{{data76|}}} |текст76 = {{{data76}}}
{{subst:!}}}}{{subst:#if:{{{class76|}}} |класс76 = {{{class76}}}
{{subst:!}}}}{{subst:#if:{{{header77|}}} |заголовок77 = {{{header77}}}
{{subst:!}}}}{{subst:#if:{{{label77|}}} |метка77 = {{{label77}}}
{{subst:!}}}}{{subst:#if:{{{data77|}}} |текст77 = {{{data77}}}
{{subst:!}}}}{{subst:#if:{{{class77|}}} |класс77 = {{{class77}}}
{{subst:!}}}}{{subst:#if:{{{header78|}}} |заголовок78 = {{{header78}}}
{{subst:!}}}}{{subst:#if:{{{label78|}}} |метка78 = {{{label78}}}
{{subst:!}}}}{{subst:#if:{{{data78|}}} |текст78 = {{{data78}}}
{{subst:!}}}}{{subst:#if:{{{class78|}}} |класс78 = {{{class78}}}
{{subst:!}}}}{{subst:#if:{{{header79|}}} |заголовок79 = {{{header79}}}
{{subst:!}}}}{{subst:#if:{{{label79|}}} |метка79 = {{{label79}}}
{{subst:!}}}}{{subst:#if:{{{data79|}}} |текст79 = {{{data79}}}
{{subst:!}}}}{{subst:#if:{{{class79|}}} |класс79 = {{{class79}}}
{{subst:!}}}}{{subst:#if:{{{header80|}}} |заголовок80 = {{{header80}}}
{{subst:!}}}}{{subst:#if:{{{label80|}}} |метка80 = {{{label80}}}
{{subst:!}}}}{{subst:#if:{{{data80|}}} |текст80 = {{{data80}}}
{{subst:!}}}}{{subst:#if:{{{class80|}}} |класс80 = {{{class80}}}
{{subst:!}}}}{{subst:#if:{{{below|}}} |внизу = {{{below}}}
{{subst:!}}}}{{subst:#if:{{{belowstyle|}}}|стиль_внизу = {{{belowstyle}}}
}}
}}|template=Карточка/импортёр|are_params=1
}}</includeonly><noinclude>{{doc}}</noinclude>
29a99ea8472f8d4050034a77d3570f625e60bf07
Шаблон:(!
10
254
669
668
2024-08-26T15:44:28Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{|</includeonly><noinclude><nowiki>{|</nowiki>{{Doc}}
</noinclude>
fc286c1b614a7c93a17dd6f17f52dba12b86e363
Шаблон:!)
10
255
671
670
2024-08-26T15:44:28Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
|}<noinclude>{{Doc}}
</noinclude>
c1895c0eccb60664bc4f2bd850d909b3c65739c3
Шаблон:Pipe
10
256
673
672
2024-08-26T15:44:34Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
|<noinclude>
{{doc}}
</noinclude>
7161a16776c0ed421759a1aee1e8f465d7b8949a
Шаблон:Импортёр шаблона-карточки
10
257
675
674
2024-08-26T15:44:35Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{ombox
| text = Это [[Википедия:Обёртки шаблонов-карточек#Импортёры|импортёр]], преобразовывающий включение шаблона {{t|{{{3|{{PAGENAME}}}}}|lang={{#if:{{{2|}}}|{{{2|}}}|en}}}} во включение шаблона {{t|{{{1}}}}}. Для его использования выполните [[Википедия:Механизм шаблонов#Подстановка|подстановку]]: скопируйте код включения шаблона {{t|{{{3|{{PAGENAME}}}}}|lang={{#if:{{{2|}}}|{{{2|}}}|en}}}} из статьи другого раздела в статью русской Википедии, замените название шаблона:
{{(!}} width="80%" align="center"
{{!}}-
{{!}} width="45%" {{!}} <p<includeonly>r</includeonly>e>{{{{{3|{{PAGENAME}}}}}
{{pipe}} ... = ...
}}</p<includeonly>r</includeonly>e>
{{!}} →
{{!}} <p<includeonly>r</includeonly>e>{{subst:{{#if:{{{1|}}}|{{{1|}}}/импортёр|{{PAGENAME}}}}
{{pipe}} ... = ...
}}</p<includeonly>r</includeonly>e>
{{!)}}
и сохраните страницу. Пожалуйста, не забывайте после этого переводить значения параметров, если и где необходимо.
}}<includeonly>{{no-doc|nocat={{{nocat|}}}|[[Категория:Импортёры шаблонов-карточек]]}}</includeonly><noinclude>{{doc}}</noinclude>
a73640b844d55fb1ba86e8b0f62016e9e86e95a8
Шаблон:Карточка/импортёр/doc
10
258
677
676
2024-08-26T15:44:35Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{docpage}}
{{Импортёр шаблона-карточки||en|Infobox}}
Этот подстановочный шаблон используется для быстрого перевода параметров карточек из английской Википедии.
Если у вас не получается добиться подстановкой данного шаблона правильного переноса шаблона-карточки из английского раздела, пожалуйста, обратитесь [[Википедия:Форум/Технический|на технический форум]] за помощью в адаптации.
456ee3241716a284eec9a77f6d33a397f9f6181c
Модуль:Карточка
828
83
678
141
2024-08-26T16:04:53Z
DuOfOrl
5
Scribunto
text/plain
local p = {}
local args = {}
local origArgs = {}
local root
local empty_row_categories = {}
local category_in_empty_row_pattern = '%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*]]'
local has_rows = false
local lists = {
plainlist_t = {
patterns = {
'^plainlist$',
'%splainlist$',
'^plainlist%s',
'%splainlist%s'
},
found = false,
styles = 'Plainlist/styles.css'
},
hlist_t = {
patterns = {
'^hlist$',
'%shlist$',
'^hlist%s',
'%shlist%s'
},
found = false,
styles = 'Hlist/styles.css'
}
}
local function has_list_class(args_to_check)
for _, list in pairs(lists) do
if not list.found then
for _, arg in pairs(args_to_check) do
for _, pattern in ipairs(list.patterns) do
if mw.ustring.find(arg or '', pattern) then
list.found = true
break
end
end
if list.found then break end
end
end
end
end
local function fixChildBoxes(sval, tt)
local function notempty( s ) return s and s:match( '%S' ) end
if notempty(sval) then
local marker = '<span class=special_infobox_marker>'
local s = sval
-- start moving templatestyles and categories inside of table rows
local slast = ''
while slast ~= s do
slast = s
s = mw.ustring.gsub(s, '(</[Tt][Rr]%s*>%s*)(%[%[%s*[Cc][Aa][Tt][Ee][Gg][Oo][Rr][Yy]%s*:[^]]*%]%])', '%2%1')
s = mw.ustring.gsub(s, '(</[Tt][Rr]%s*>%s*)(\127[^\127]*UNIQ%-%-templatestyles%-%x+%-QINU[^\127]*\127)', '%2%1')
end
-- end moving templatestyles and categories inside of table rows
s = mw.ustring.gsub(s, '(<%s*[Tt][Rr])', marker .. '%1')
s = mw.ustring.gsub(s, '(</[Tt][Rr]%s*>)', '%1' .. marker)
if s:match(marker) then
s = mw.ustring.gsub(s, marker .. '%s*' .. marker, '')
s = mw.ustring.gsub(s, '([\r\n]|-[^\r\n]*[\r\n])%s*' .. marker, '%1')
s = mw.ustring.gsub(s, marker .. '%s*([\r\n]|-)', '%1')
s = mw.ustring.gsub(s, '(</[Cc][Aa][Pp][Tt][Ii][Oo][Nn]%s*>%s*)' .. marker, '%1')
s = mw.ustring.gsub(s, '(<%s*[Tt][Aa][Bb][Ll][Ee][^<>]*>%s*)' .. marker, '%1')
s = mw.ustring.gsub(s, '^(%{|[^\r\n]*[\r\n]%s*)' .. marker, '%1')
s = mw.ustring.gsub(s, '([\r\n]%{|[^\r\n]*[\r\n]%s*)' .. marker, '%1')
s = mw.ustring.gsub(s, marker .. '(%s*</[Tt][Aa][Bb][Ll][Ee]%s*>)', '%1')
s = mw.ustring.gsub(s, marker .. '(%s*\n|%})', '%1')
end
if s:match(marker) then
local subcells = mw.text.split(s, marker)
s = ''
for k = 1, #subcells do
if k == 1 then
s = s .. subcells[k] .. '</' .. tt .. '></tr>'
elseif k == #subcells then
local rowstyle = ' style="display:none"'
if notempty(subcells[k]) then rowstyle = '' end
s = s .. '<tr' .. rowstyle ..'><' .. tt .. ' colspan=2>\n' ..
subcells[k]
elseif notempty(subcells[k]) then
if (k % 2) == 0 then
s = s .. subcells[k]
else
s = s .. '<tr><' .. tt .. ' colspan=2>\n' ..
subcells[k] .. '</' .. tt .. '></tr>'
end
end
end
end
-- the next two lines add a newline at the end of lists for the PHP parser
-- [[Special:Diff/849054481]]
-- remove when [[:phab:T191516]] is fixed or OBE
s = mw.ustring.gsub(s, '([\r\n][%*#;:][^\r\n]*)$', '%1\n')
s = mw.ustring.gsub(s, '^([%*#;:][^\r\n]*)$', '%1\n')
s = mw.ustring.gsub(s, '^([%*#;:])', '\n%1')
s = mw.ustring.gsub(s, '^(%{%|)', '\n%1')
return s
else
return sval
end
end
-- Cleans empty tables
local function cleanInfobox()
root = tostring(root)
if has_rows == false then
root = mw.ustring.gsub(root, '<table[^<>]*>%s*</table>', '')
end
end
-- Returns the union of the values of two tables, as a sequence.
local function union(t1, t2)
local vals = {}
for k, v in pairs(t1) do
vals[v] = true
end
for k, v in pairs(t2) do
vals[v] = true
end
local ret = {}
for k, v in pairs(vals) do
table.insert(ret, k)
end
return ret
end
-- Returns a table containing the numbers of the arguments that exist
-- for the specified prefix. For example, if the prefix was 'data', and
-- 'data1', 'data2', and 'data5' exist, it would return {1, 2, 5}.
local function getArgNums(prefix)
local nums = {}
for k, v in pairs(args) do
local num = tostring(k):match('^' .. prefix .. '([1-9]%d*)$')
if num then table.insert(nums, tonumber(num)) end
end
table.sort(nums)
return nums
end
-- Adds a row to the infobox, with either a header cell
-- or a label/data cell combination.
local function addRow(rowArgs)
if rowArgs.header and rowArgs.header ~= '_BLANK_' then
has_rows = true
has_list_class({ rowArgs.rowclass, rowArgs.class, args.headerclass })
root
:tag('tr')
:addClass(rowArgs.rowclass)
:cssText(rowArgs.rowstyle)
:tag('th')
:attr('colspan', '2')
:addClass('infobox-header')
:addClass(rowArgs.class)
:addClass(args.headerclass)
-- @deprecated next; target .infobox-<name> .infobox-header
:cssText(args.headerstyle)
:cssText(rowArgs.rowcellstyle)
:wikitext(fixChildBoxes(rowArgs.header, 'th'))
if rowArgs.data then
root:wikitext(
'[[Category:Pages using infobox templates with ignored data cells]]'
)
end
elseif rowArgs.data and rowArgs.data:gsub(category_in_empty_row_pattern, ''):match('^%S') then
has_rows = true
has_list_class({ rowArgs.rowclass, rowArgs.class })
local row = root:tag('tr')
row:addClass(rowArgs.rowclass)
row:cssText(rowArgs.rowstyle)
if rowArgs.label then
row
:tag('th')
:attr('scope', 'row')
:addClass('infobox-label')
-- @deprecated next; target .infobox-<name> .infobox-label
:cssText(args.labelstyle)
:cssText(rowArgs.rowcellstyle)
:wikitext(rowArgs.label)
:done()
end
local dataCell = row:tag('td')
dataCell
:attr('colspan', not rowArgs.label and '2' or nil)
:addClass(not rowArgs.label and 'infobox-full-data' or 'infobox-data')
:addClass(rowArgs.class)
-- @deprecated next; target .infobox-<name> .infobox(-full)-data
:cssText(rowArgs.datastyle)
:cssText(rowArgs.rowcellstyle)
:wikitext(fixChildBoxes(rowArgs.data, 'td'))
else
table.insert(empty_row_categories, rowArgs.data or '')
end
end
local function renderTitle()
if not args.title then return end
has_rows = true
has_list_class({args.titleclass})
root
:tag('caption')
:addClass('infobox-title')
:addClass(args.titleclass)
-- @deprecated next; target .infobox-<name> .infobox-title
:cssText(args.titlestyle)
:wikitext(args.title)
end
local function renderAboveRow()
if not args.above then return end
has_rows = true
has_list_class({ args.aboveclass })
root
:tag('tr')
:tag('th')
:attr('colspan', '2')
:addClass('infobox-above')
:addClass(args.aboveclass)
-- @deprecated next; target .infobox-<name> .infobox-above
:cssText(args.abovestyle)
:wikitext(fixChildBoxes(args.above,'th'))
end
local function renderBelowRow()
if not args.below then return end
has_rows = true
has_list_class({ args.belowclass })
root
:tag('tr')
:tag('td')
:attr('colspan', '2')
:addClass('infobox-below')
:addClass(args.belowclass)
-- @deprecated next; target .infobox-<name> .infobox-below
:cssText(args.belowstyle)
:wikitext(fixChildBoxes(args.below,'td'))
end
local function addSubheaderRow(subheaderArgs)
if subheaderArgs.data and
subheaderArgs.data:gsub(category_in_empty_row_pattern, ''):match('^%S') then
has_rows = true
has_list_class({ subheaderArgs.rowclass, subheaderArgs.class })
local row = root:tag('tr')
row:addClass(subheaderArgs.rowclass)
local dataCell = row:tag('td')
dataCell
:attr('colspan', '2')
:addClass('infobox-subheader')
:addClass(subheaderArgs.class)
:cssText(subheaderArgs.datastyle)
:cssText(subheaderArgs.rowcellstyle)
:wikitext(fixChildBoxes(subheaderArgs.data, 'td'))
else
table.insert(empty_row_categories, subheaderArgs.data or '')
end
end
local function renderSubheaders()
if args.subheader then
args.subheader1 = args.subheader
end
if args.subheaderrowclass then
args.subheaderrowclass1 = args.subheaderrowclass
end
local subheadernums = getArgNums('subheader')
for k, num in ipairs(subheadernums) do
addSubheaderRow({
data = args['subheader' .. tostring(num)],
-- @deprecated next; target .infobox-<name> .infobox-subheader
datastyle = args.subheaderstyle,
rowcellstyle = args['subheaderstyle' .. tostring(num)],
class = args.subheaderclass,
rowclass = args['subheaderrowclass' .. tostring(num)]
})
end
end
local function addImageRow(imageArgs)
if imageArgs.data and
imageArgs.data:gsub(category_in_empty_row_pattern, ''):match('^%S') then
has_rows = true
has_list_class({ imageArgs.rowclass, imageArgs.class })
local row = root:tag('tr')
row:addClass(imageArgs.rowclass)
local dataCell = row:tag('td')
dataCell
:attr('colspan', '2')
:addClass('infobox-image')
:addClass(imageArgs.class)
:cssText(imageArgs.datastyle)
:wikitext(fixChildBoxes(imageArgs.data, 'td'))
else
table.insert(empty_row_categories, imageArgs.data or '')
end
end
local function renderImages()
if args.image then
args.image1 = args.image
end
if args.caption then
args.caption1 = args.caption
end
local imagenums = getArgNums('image')
for k, num in ipairs(imagenums) do
local caption = args['caption' .. tostring(num)]
local data = mw.html.create():wikitext(args['image' .. tostring(num)])
if caption then
data
:tag('div')
:addClass('infobox-caption')
-- @deprecated next; target .infobox-<name> .infobox-caption
:cssText(args.captionstyle)
:wikitext(caption)
end
addImageRow({
data = tostring(data),
-- @deprecated next; target .infobox-<name> .infobox-image
datastyle = args.imagestyle,
class = args.imageclass,
rowclass = args['imagerowclass' .. tostring(num)]
})
end
end
-- When autoheaders are turned on, preprocesses the rows
local function preprocessRows()
if not args.autoheaders then return end
local rownums = union(getArgNums('header'), getArgNums('data'))
table.sort(rownums)
local lastheader
for k, num in ipairs(rownums) do
if args['header' .. tostring(num)] then
if lastheader then
args['header' .. tostring(lastheader)] = nil
end
lastheader = num
elseif args['data' .. tostring(num)] and
args['data' .. tostring(num)]:gsub(
category_in_empty_row_pattern, ''
):match('^%S') then
local data = args['data' .. tostring(num)]
if data:gsub(category_in_empty_row_pattern, ''):match('%S') then
lastheader = nil
end
end
end
if lastheader then
args['header' .. tostring(lastheader)] = nil
end
end
-- Gets the union of the header and data argument numbers,
-- and renders them all in order
local function renderRows()
local rownums = union(getArgNums('header'), getArgNums('data'))
table.sort(rownums)
for k, num in ipairs(rownums) do
addRow({
header = args['header' .. tostring(num)],
label = args['label' .. tostring(num)],
data = args['data' .. tostring(num)],
datastyle = args.datastyle,
class = args['class' .. tostring(num)],
rowclass = args['rowclass' .. tostring(num)],
-- @deprecated next; target .infobox-<name> rowclass
rowstyle = args['rowstyle' .. tostring(num)],
rowcellstyle = args['rowcellstyle' .. tostring(num)]
})
end
end
local function renderNavBar()
if not args.name then return end
has_rows = true
root
:tag('tr')
:tag('td')
:attr('colspan', '2')
:addClass('infobox-navbar')
:wikitext(require('Module:Navbar')._navbar{
args.name,
mini = 1,
})
end
local function renderItalicTitle()
local italicTitle = args['italic title'] and mw.ustring.lower(args['italic title'])
if italicTitle == '' or italicTitle == 'force' or italicTitle == 'yes' then
root:wikitext(require('Module:Italic title')._main({}))
end
end
-- Categories in otherwise empty rows are collected in empty_row_categories.
-- This function adds them to the module output. It is not affected by
-- args.decat because this module should not prevent module-external categories
-- from rendering.
local function renderEmptyRowCategories()
for _, s in ipairs(empty_row_categories) do
root:wikitext(s)
end
end
-- Render tracking categories. args.decat == turns off tracking categories.
local function renderTrackingCategories()
if args.decat == 'yes' then return end
if args.child == 'yes' then
if args.title then
root:wikitext(
'[[Category:Pages using embedded infobox templates with the title parameter]]'
)
end
elseif #(getArgNums('data')) == 0 and mw.title.getCurrentTitle().namespace == 0 then
root:wikitext('[[Category:Articles using infobox templates with no data rows]]')
end
end
--[=[
Loads the templatestyles for the infobox.
TODO: FINISH loading base templatestyles here rather than in
MediaWiki:Common.css. There are 4-5000 pages with 'raw' infobox tables.
See [[Mediawiki_talk:Common.css/to_do#Infobox]] and/or come help :).
When we do this we should clean up the inline CSS below too.
Will have to do some bizarre conversion category like with sidebar.
]=]
local function loadTemplateStyles()
local frame = mw.getCurrentFrame()
local hlist_templatestyles = ''
if lists.hlist_t.found then
hlist_templatestyles = frame:extensionTag{
name = 'templatestyles', args = { src = lists.hlist_t.styles }
}
end
local plainlist_templatestyles = ''
if lists.plainlist_t.found then
plainlist_templatestyles = frame:extensionTag{
name = 'templatestyles', args = { src = lists.plainlist_t.styles }
}
end
-- See function description
local base_templatestyles = frame:extensionTag{
name = 'templatestyles', args = { src = 'Module:Infobox/styles.css' }
}
local templatestyles = ''
if args['templatestyles'] then
templatestyles = frame:extensionTag{
name = 'templatestyles', args = { src = args['templatestyles'] }
}
end
local child_templatestyles = ''
if args['child templatestyles'] then
child_templatestyles = frame:extensionTag{
name = 'templatestyles', args = { src = args['child templatestyles'] }
}
end
local grandchild_templatestyles = ''
if args['grandchild templatestyles'] then
grandchild_templatestyles = frame:extensionTag{
name = 'templatestyles', args = { src = args['grandchild templatestyles'] }
}
end
return table.concat({
-- hlist -> plainlist -> base is best-effort to preserve old Common.css ordering.
-- this ordering is not a guarantee because the rows of interest invoking
-- each class may not be on a specific page
hlist_templatestyles,
plainlist_templatestyles,
base_templatestyles,
templatestyles,
child_templatestyles,
grandchild_templatestyles
})
end
-- common functions between the child and non child cases
local function structure_infobox_common()
renderSubheaders()
renderImages()
preprocessRows()
renderRows()
renderBelowRow()
renderNavBar()
renderItalicTitle()
renderEmptyRowCategories()
renderTrackingCategories()
cleanInfobox()
end
-- Specify the overall layout of the infobox, with special settings if the
-- infobox is used as a 'child' inside another infobox.
local function _infobox()
if args.child ~= 'yes' then
root = mw.html.create('table')
root
:addClass(args.subbox == 'yes' and 'infobox-subbox' or 'infobox')
:addClass(args.bodyclass)
-- @deprecated next; target .infobox-<name>
:cssText(args.bodystyle)
has_list_class({ args.bodyclass })
renderTitle()
renderAboveRow()
else
root = mw.html.create()
root
:wikitext(args.title)
end
structure_infobox_common()
return loadTemplateStyles() .. root
end
-- If the argument exists and isn't blank, add it to the argument table.
-- Blank arguments are treated as nil to match the behaviour of ParserFunctions.
local function preprocessSingleArg(argName)
if origArgs[argName] and origArgs[argName] ~= '' then
args[argName] = origArgs[argName]
end
end
-- Assign the parameters with the given prefixes to the args table, in order, in
-- batches of the step size specified. This is to prevent references etc. from
-- appearing in the wrong order. The prefixTable should be an array containing
-- tables, each of which has two possible fields, a "prefix" string and a
-- "depend" table. The function always parses parameters containing the "prefix"
-- string, but only parses parameters in the "depend" table if the prefix
-- parameter is present and non-blank.
local function preprocessArgs(prefixTable, step)
if type(prefixTable) ~= 'table' then
error("Non-table value detected for the prefix table", 2)
end
if type(step) ~= 'number' then
error("Invalid step value detected", 2)
end
-- Get arguments without a number suffix, and check for bad input.
for i,v in ipairs(prefixTable) do
if type(v) ~= 'table' or type(v.prefix) ~= "string" or
(v.depend and type(v.depend) ~= 'table') then
error('Invalid input detected to preprocessArgs prefix table', 2)
end
preprocessSingleArg(v.prefix)
-- Only parse the depend parameter if the prefix parameter is present
-- and not blank.
if args[v.prefix] and v.depend then
for j, dependValue in ipairs(v.depend) do
if type(dependValue) ~= 'string' then
error('Invalid "depend" parameter value detected in preprocessArgs')
end
preprocessSingleArg(dependValue)
end
end
end
-- Get arguments with number suffixes.
local a = 1 -- Counter variable.
local moreArgumentsExist = true
while moreArgumentsExist == true do
moreArgumentsExist = false
for i = a, a + step - 1 do
for j,v in ipairs(prefixTable) do
local prefixArgName = v.prefix .. tostring(i)
if origArgs[prefixArgName] then
-- Do another loop if any arguments are found, even blank ones.
moreArgumentsExist = true
preprocessSingleArg(prefixArgName)
end
-- Process the depend table if the prefix argument is present
-- and not blank, or we are processing "prefix1" and "prefix" is
-- present and not blank, and if the depend table is present.
if v.depend and (args[prefixArgName] or (i == 1 and args[v.prefix])) then
for j,dependValue in ipairs(v.depend) do
local dependArgName = dependValue .. tostring(i)
preprocessSingleArg(dependArgName)
end
end
end
end
a = a + step
end
end
-- Parse the data parameters in the same order that the old {{infobox}} did, so
-- that references etc. will display in the expected places. Parameters that
-- depend on another parameter are only processed if that parameter is present,
-- to avoid phantom references appearing in article reference lists.
local function parseDataParameters()
preprocessSingleArg('autoheaders')
preprocessSingleArg('child')
preprocessSingleArg('bodyclass')
preprocessSingleArg('subbox')
preprocessSingleArg('bodystyle')
preprocessSingleArg('title')
preprocessSingleArg('titleclass')
preprocessSingleArg('titlestyle')
preprocessSingleArg('above')
preprocessSingleArg('aboveclass')
preprocessSingleArg('abovestyle')
preprocessArgs({
{prefix = 'subheader', depend = {'subheaderstyle', 'subheaderrowclass'}}
}, 10)
preprocessSingleArg('subheaderstyle')
preprocessSingleArg('subheaderclass')
preprocessArgs({
{prefix = 'image', depend = {'caption', 'imagerowclass'}}
}, 10)
preprocessSingleArg('captionstyle')
preprocessSingleArg('imagestyle')
preprocessSingleArg('imageclass')
preprocessArgs({
{prefix = 'header'},
{prefix = 'data', depend = {'label'}},
{prefix = 'rowclass'},
{prefix = 'rowstyle'},
{prefix = 'rowcellstyle'},
{prefix = 'class'}
}, 50)
preprocessSingleArg('headerclass')
preprocessSingleArg('headerstyle')
preprocessSingleArg('labelstyle')
preprocessSingleArg('datastyle')
preprocessSingleArg('below')
preprocessSingleArg('belowclass')
preprocessSingleArg('belowstyle')
preprocessSingleArg('name')
-- different behaviour for italics if blank or absent
args['italic title'] = origArgs['italic title']
preprocessSingleArg('decat')
preprocessSingleArg('templatestyles')
preprocessSingleArg('child templatestyles')
preprocessSingleArg('grandchild templatestyles')
end
-- If called via #invoke, use the args passed into the invoking template.
-- Otherwise, for testing purposes, assume args are being passed directly in.
function p.infobox(frame)
if frame == mw.getCurrentFrame() then
origArgs = frame:getParent().args
else
origArgs = frame
end
parseDataParameters()
return _infobox()
end
-- For calling via #invoke within a template
function p.infoboxTemplate(frame)
origArgs = {}
for k,v in pairs(frame.args) do origArgs[k] = mw.text.trim(v) end
parseDataParameters()
return _infobox()
end
return p
0ddb7e5c8426d67cd589b710efb9912ddfb67fea
Шаблон:Политик
10
259
680
679
2024-08-26T16:45:34Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{Карточка
|имя = Политик
|from = {{{from|}}}
|стиль_меток = min-width:9em;
|вверху = {{карточка/имя|{{{имя|{{{Имя|}}}}}}|from={{{from|}}}}}
|вверху2 = {{карточка/оригинал имени|{{{оригинал имени|{{{Оригинал имени|}}}}}}|from={{{from|}}}}}
|изображение = {{wikidata|p18|{{{изображение|{{{Изображение|}}}}}}|size={{{ширина|{{{Ширина|}}}}}}|caption={{{описание изображения|{{{Описание изображения|}}}}}}|from={{{from|}}}}}
|метка1 = Имя при рождении
|текст1 = {{{имя при рождении|{{{Имя при рождении|}}}}}}
|метка2 = Псевдонимы
|текст2 = {{{псевдонимы|{{{Псевдонимы|}}}}}}
|метка3 = Дата рождения
|текст3 = {{wikidata/p569|{{{дата рождения|{{{Дата рождения|}}}}}}|{{{дата смерти|{{{Дата смерти|}}}}}}|from={{{from|}}}}}
|метка4 = Место рождения
|текст4 = {{{место рождения|{{{Место рождения|}}}}}}
|викиданные4 = p19
|метка5 = Дата смерти
|текст5 = {{wikidata/p570|{{{дата смерти|{{{Дата смерти|}}}}}}|{{{дата рождения|{{{Дата рождения|}}}}}}|from={{{from|}}}}}
|метка6 = Место смерти
|текст6 = {{{место смерти|{{{Место смерти|}}}}}}
|викиданные6 = p20
|метка7 = Гражданство
|текст7 = {{{страна|{{{гражданство|{{{подданство|{{{Гражданство|}}}}}}}}}}}}
|викиданные7 = p27
|метка8 = Род деятельности
|текст8 = {{{род деятельности|{{{Род деятельности|}}}}}}
|викиданные8 = p106
|метка9 = Образование
|текст9 = {{{образование|{{{альма-матер|{{{Образование|}}}}}}}}}
|викиданные9 = p69
|метка10 = Учёная степень
|текст10 = {{{учёная степень|{{{Учёная степень|}}}}}}
|викиданные10 = p512
|метка11 = Учёное звание
|текст11 = {{{учёное звание|{{{Учёное звание|}}}}}}
|метка12 = Вероисповедание
|текст12 = {{{вероисповедание|{{{Вероисповедание|}}}}}}
|викиданные12 = p140
|метка13 = Партия
|текст13 = {{{партия|{{{Партия|}}}}}}
|викиданные13 = p102
|метка14 = Основные идеи
|текст14 = {{{основные идеи|{{{Основные идеи|}}}}}}
|викиданные14 = p1142
|метка15 = Отец
|текст15 = {{{отец|{{{Отец|}}}}}}
|викиданные15 = p22
|метка16 = Мать
|текст16 = {{{мать|{{{Мать|}}}}}}
|викиданные16 = p25
|метка17 = {{wikidata gender switch||Супруг|Супруга|Супруг(а)}}
|текст17 = {{wikidata|p26|{{#if: {{{супруга|{{{Супруга|}}}}}} | {{{супруга|{{{Супруга|}}}}}} | {{{супруг|{{{Супруг|}}}}}} }}}}
|метка18 = Дети
|текст18 = {{{дети|{{{Дети|}}}}}}
|викиданные18 = p40
|метка19 = Награды
|текст19 = {{{награды|{{{награды и премии|{{{Награды|}}}}}}}}}
|викиданные19 = p166
|метка20 = Автограф
|текст20 = {{wikidata|p109|{{{автограф|{{{Автограф|}}}}}}|size={{#if:{{{ширина автографа|{{{Ширина автографа|}}}}}}|{{{ширина автографа|{{{Ширина автографа}}}}}}|143x143}}|alt=Автограф|from={{{from|}}}}}
|внизу = {{wikidata|p856|{{{сайт|{{{Сайт|}}}}}}|from={{{from|}}}}}
|внизу2 = {{карточка/Викисклад|{{{викисклад|{{{Викисклад|}}}}}}|from={{{from|}}}}}
}}<!--
-->{{#if:{{NAMESPACE}}{{{nocat|}}}||<!--
-->[[Категория:Персоналии по алфавиту]]<!--
-->[[Категория:Политики по алфавиту]]<!--
-->{{#invoke:Wikidata/category|categorizeIfNoParams}}<!--
-->{{#invoke:CategoryForProfession|mainFunction}}<!--
-->{{Сортировка: по изображениям|{{{изображение|{{{Изображение|}}}}}}|from={{{from|}}}|nocat={{{nocat|}}}|default-type=человек|default-occupation=политик}}<!--
-->}}<!--
-->{{#invoke:check for unknown parameters|check
| unknown = {{#if: {{NAMESPACE}} || [[Категория:Страницы с неизвестными параметрами шаблона Политик|_VALUE_]] }}
| ignoreblank =
| preview = <span class="error">Неизвестный параметр «_VALUE_» шаблона Политик</span>
| showblankpositional= 1
|from|nocat|Автограф|Вероисповедание|Викисклад|Гражданство|Дата рождения|Дата смерти|Дети|Изображение|Имя|Имя при рождении|Мать|Место рождения|Место смерти|Награды|Образование|Описание изображения|Оригинал имени|Основные идеи|Отец|Партия|Псевдонимы|Род деятельности|Сайт|Супруг|Супруга|Учёная степень|Учёное звание|Ширина|Ширина автографа<!--
-->|автограф|вероисповедание|викисклад|гражданство|дата рождения|дата смерти|дети|изображение|имя|имя при рождении|мать|место рождения|место смерти|награды|образование|описание изображения|оригинал имени|основные идеи|отец|партия|псевдонимы|род деятельности|сайт|супруг|супруга|учёная степень|учёное звание|ширина|ширина автографа |альма-матер|страна|подданство|награды и премии
}}<!--
--><noinclude>{{doc}}</noinclude>
6e99fb4d8a3ec44096ba8d60276e31241c0d8f65
Шаблон:Хх
10
260
682
681
2024-08-26T16:45:41Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
[[<noinclude>
{{doc}}
<!-- Пожалуйста, добавляйте категории и интервики на страницу документации! --></noinclude>
c18d284eaccac8b03717d7977a4bd795d3ad7f3c
Шаблон:Wikidata
10
261
684
683
2024-08-26T16:45:42Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{#invoke:Wikidata|formatProperty|property={{{1|}}}|value={{{2|}}}}}</includeonly><noinclude>{{doc}}</noinclude>
9d3d422eca39504b018df6ec0bb047392a7aba7e
Модуль:Wikidata
828
262
686
685
2024-08-26T16:45:44Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
---settings, may differ from project to project
local fileDefaultSize = '267x400px'
local outputReferences = true
local writingSystemElementId = 'Q8209'
local langElementId = 'Q7737'
---Ссылки на используемые модули, которые потребуются в 99% случаев загрузки страниц (чтобы иметь на виду при переименовании)
local moduleSources = require( 'Module:Sources' )
local WDS = require( 'Module:WikidataSelectors' )
---Константы
---@type string
local CONTENT_LANGUAGE_CODE = mw.language.getContentLanguage():getCode()
local p = {}
local g_config, g_frame
local formatDatavalue, formatEntityId, formatRefs, formatSnak, formatStatement,
formatStatementDefault, getSourcingCircumstances, getPropertyParams
---@param obj table
---@param target table
---@param skipEmpty boolean | nil
---@return table
local function copyTo( obj, target, skipEmpty )
for key, val in pairs( obj ) do
if skipEmpty ~= true or ( val ~= nil and val ~= '' ) then
target[ key ] = val
end
end
return target
end
---@param prev number | nil
---@param next number | nil
---@return number | nil
local function min( prev, next )
if prev == nil or prev > next then
return next
end
return prev
end
---@param prev number | nil
---@param next number | nil
---@return number | nil
local function max( prev, next )
if prev == nil or prev < next then
return next
end
return prev
end
---@param section string
---@param code string
---@return any | nil
local function getConfig( section, code )
if g_config == nil then
g_config = require( 'Module:Wikidata/config' )
end
if not g_config then
g_config = {}
end
if not section then
return g_config
end
if not code then
return g_config[ section ] or {}
end
if not g_config[ section ] then
return nil
end
return g_config[ section ][ code ]
end
---@param code string
---@param sortKey string | nil
---@return string
local function getCategoryByCode( code, sortKey )
local value = getConfig( 'categories', code )
if not value or value == '' then
return ''
end
if sortKey ~= nil then
return '[[Category:' .. value .. '|' .. sortKey .. ']]'; -- экранировать?
else
return '[[Category:' .. value .. ']]'
end
end
---@param isoStr string | table
---@return table | nil
local function splitISO8601( isoStr )
if 'table' == type( isoStr ) then
if isoStr.args and isoStr.args[ 1 ] then
isoStr = '' .. isoStr.args[ 1 ]
else
return 'unknown argument type: ' .. type( isoStr ) .. ': ' .. table.tostring( isoStr )
end
end
local Y, M, D = ( function( str )
local pattern = "(%-?%d+)%-(%d+)%-(%d+)T"
local _Y, _M, _D = mw.ustring.match( str, pattern )
return tonumber( _Y ), tonumber( _M ), tonumber( _D )
end )( isoStr )
local h, m, s = ( function( str )
local pattern = "T(%d+):(%d+):(%d+)%Z"
local _H, _M, _S = mw.ustring.match( str, pattern )
return tonumber( _H ), tonumber( _M ), tonumber( _S )
end )( isoStr )
local oh, om = ( function( str )
if str:sub(-1) == "Z" then -- ends with Z, Zulu time
return 0, 0
end
-- matches ±hh:mm, ±hhmm or ±hh; else returns nils
local pattern = "([-+])(%d%d):?(%d?%d?)$"
local sign, oh, om = mw.ustring.match( str, pattern )
sign, oh, om = sign or "+", oh or "00", om or "00"
return tonumber( sign .. oh ), tonumber( sign .. om )
end )( isoStr )
return { year=Y, month=M, day=D, hour=( h + oh ), min=( m + om ), sec=s }
end
---Внутренняя функции для получения границ временного диапазона
---@param time string
---@param precision number
---@return table | nil
function p._parseTimeBoundaries( time, precision )
local s = splitISO8601( time )
if not s then
return nil
end
if precision >= 0 and precision <= 8 then
local powers = { 1000000000 , 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10 }
local power = powers[ precision + 1 ]
local left = s.year - ( s.year % power )
return { tonumber( os.time( { year=left, month=1, day=1, hour=0, min=0, sec=0 } ) ) * 1000,
tonumber( os.time( { year=left + power - 1, month=12, day=31, hour=29, min=59, sec=58 } ) ) * 1000 + 1999 }
end
if precision == 9 then
return { tonumber( os.time( { year=s.year, month=1, day=1, hour=0, min=0, sec=0} )) * 1000,
tonumber( os.time( { year=s.year, month=12, day=31, hour=23, min=59, sec=58} )) * 1000 + 1999 }
end
if precision == 10 then
local lastDays = { 31, 28.25, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
local lastDay = lastDays[ s.month ]
return { tonumber( os.time( { year=s.year, month=s.month, day=1, hour=0, min=0, sec=0 } ) ) * 1000,
tonumber( os.time( { year=s.year, month=s.month, day=lastDay, hour=23, min=59, sec=58 } ) ) * 1000 + 1999 }
end
if precision == 11 then
return { tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=0, min=0, sec=0 } ) ) * 1000,
tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=23, min=59, sec=58 } ) ) * 1000 + 1999 }
end
if precision == 12 then
return { tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=0, sec=0 } ) ) * 1000,
tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=59, sec=58 } ) ) * 1000 + 1999 }
end
if precision == 13 then
return { tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=s.min, sec=0 } ) ) * 1000,
tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=s.min, sec=58 } ) ) * 1000 + 1999 }
end
if precision == 14 then
local t = tonumber( os.time( { year=s.year, month=s.month, day=s.day, hour=s.hour, min=s.min, sec=0 } ) )
return { t * 1000, t * 1000 + 999 }
end
error( 'Unsupported precision: ' .. precision )
end
---Внутренняя функция для получения числового значения времени из snak'а
---@param table snak
---@return number | nil
function p._parseTimeFromSnak( snak )
if snak and snak.datavalue and snak.datavalue.value and snak.datavalue.value.time then
local timeData = splitISO8601( tostring( snak.datavalue.value.time ) )
timeData.month = math.max( timeData.month, 1 )
timeData.day = math.max( timeData.day, 1 )
return tonumber( os.time( timeData ) ) * 1000
end
return nil
end
---Функция для формирования категории на основе wikidata/config
---@param options table
---@param entityId string
---@return string
local function extractCategory( options, entityId )
if not entityId or not options.category or options.nocat then
return ''
end
if type( entityId ) ~= 'string' then
entityId = entityId.id
end
local claims = WDS.load( entityId, options.category )
if not claims then
return ''
end
for _, claim in pairs( claims ) do
if claim
and claim.mainsnak
and claim.mainsnak.datavalue
and claim.mainsnak.datavalue.type == 'wikibase-entityid'
then
local catEntityId = claim.mainsnak.datavalue.value.id
local wbStatus, catSiteLink = pcall( mw.wikibase.getSitelink, catEntityId )
if wbStatus and catSiteLink then
return '[[' .. catSiteLink .. ']]'
end
end
end
return ''
end
---Преобразует строку в булевое значение
---@param valueToParse string
---@return boolean Преобразованное значение, если его удалось распознать, или defaultValue во всех остальных случаях
local function toBoolean( valueToParse, defaultValue )
if valueToParse ~= nil then
if valueToParse == false or valueToParse == '' or valueToParse == 'false' or valueToParse == '0' then
return false
end
return true
end
return defaultValue
end
---Обрачивает отформатированное значение в инлайновый или блочный тег.
---@param value string value
---@param attributes table of attributes
---@return string HTML tag with value
local function wrapValue( value, attributes )
local tagName = 'span'
local spacer = ''
if string.match( value, '\n' )
or string.match( value, '<t[dhr][ >]' )
or string.match( value, '<div[ >]' )
or string.find( value, 'UNIQ%-%-imagemap' )
then
tagName = 'div'
spacer = '\n'
end
local attrString = ''
for key, val in pairs( attributes or {} ) do
local _key = mw.text.trim( key )
local _value = mw.text.encode( mw.text.trim( val ) )
attrString = attrString .. _key .. '="' .. _value .. '" '
end
return '<' .. tagName .. ' ' .. attrString .. '>' .. spacer .. value .. '</' .. tagName .. '>'
end
---Wraps formatted snak value into HTML tag with attributes.
---@param value string value of snak
---@param hash string
---@param attributes table of extra attributes
---@return string HTML tag with value
local function wrapSnak( value, hash, attributes )
local newAttributes = mw.clone( attributes or {} )
newAttributes[ 'class' ] = ( newAttributes[ 'class' ] or '' ) .. ' wikidata-snak'
if hash then
newAttributes[ 'data-wikidata-hash'] = hash
else
newAttributes[ 'class' ] = newAttributes[ 'class' ] .. ' wikidata-main-snak'
end
return wrapValue( value, newAttributes )
end
---Wraps formatted statement value into HTML tag with attributes.
---@param value string value of statement
---@param propertyId string PID of property
---@param claimId string ID of claim or nil for local value
---@param attributes table of extra attributes
---@return string HTML tag with value
local function wrapStatement( value, propertyId, claimId, attributes )
local newAttributes = mw.clone( attributes or {} )
newAttributes[ 'class' ] = newAttributes[ 'class' ] or ''
newAttributes[ 'data-wikidata-property-id' ] = string.upper( propertyId )
if claimId then
newAttributes[ 'class' ] = newAttributes[ 'class' ] .. ' wikidata-claim'
newAttributes[ 'data-wikidata-claim-id' ] = claimId
else
newAttributes[ 'class' ] = newAttributes[ 'class' ] .. ' no-wikidata'
end
return wrapValue( value, newAttributes )
end
---Wraps formatted qualifier's statement value into HTML tag with attributes.
---@param value string value of qualifier's statement
---@param qualifierId string PID of qualifier
---@param attributes table of extra attributes
---@return string HTML tag with value
local function wrapQualifier( value, qualifierId, attributes )
local newAttributes = mw.clone( attributes or {} )
newAttributes[ 'data-wikidata-qualifier-id' ] = string.upper( qualifierId )
return wrapValue( value, newAttributes )
end
---Функция для получения сущности (еntity) для текущей страницы
---Подробнее о сущностях см. d:Wikidata:Glossary/ru
---@param id string Идентификатор (типа P18, Q42)
---@return table Таблица, элементы которой индексируются с нуля
local function getEntityFromId( id )
local entity
local wbStatus
if id then
wbStatus, entity = pcall( mw.wikibase.getEntity, id )
else
wbStatus, entity = pcall( mw.wikibase.getEntity )
end
return entity
end
---Внутренняя функция для формирования сообщения об ошибке
---@param key string Ключ элемента в таблице config.errors (например entity-not-found)
---@return void
local function throwError( key )
error( getConfig( 'errors', key ) )
end
---Функция для получения идентификатора сущностей
---@param value table
---@return string
local function getEntityIdFromValue( value )
local prefix = ''
if value[ 'entity-type' ] == 'item' then
prefix = 'Q'
elseif value[ 'entity-type' ] == 'property' then
prefix = 'P'
else
throwError( 'unknown-entity-type' )
end
return prefix .. value[ 'numeric-id' ]
end
---Проверка на наличие специализированной функции в опциях
---@param options table
---@param prefix string
---@return function
local function getUserFunction( options, prefix, defaultFunction )
-- проверка на указание специализированных обработчиков в параметрах,
-- переданных при вызове
if options[ prefix .. '-module' ] or options[ prefix .. '-function' ] then
-- проверка на пустые строки в параметрах или их отсутствие
if not options[ prefix .. '-module' ] or not options[ prefix .. '-function' ] then
throwError( 'unknown-' .. prefix .. '-module' )
end
-- динамическая загруза модуля с обработчиком указанным в параметре
local formatter = require( 'Module:' .. options[ prefix .. '-module' ] )
if formatter == nil then
throwError( prefix .. '-module-not-found' )
end
local fun = formatter[ options[ prefix .. '-function' ] ]
if fun == nil then
throwError( prefix .. '-function-not-found' )
end
return fun
end
return defaultFunction
end
---Выбирает свойства по property id, дополнительно фильтруя их по рангу
---@param context table
---@param options table
---@param propertySelector string
---@return table | nil
local function selectClaims( context, options, propertySelector )
if not context then error( 'context not specified' ); end
if not options then error( 'options not specified' ); end
if not options.entityId then error( 'options.entity is missing' ); end
if not propertySelector then error( 'propertySelector not specified' ); end
local result = WDS.load( options.entityId, propertySelector )
if not result or #result == 0 then
return nil
end
if options.limit and options.limit ~= '' and options.limit ~= '-' then
local limit = tonumber( options.limit, 10 )
while #result > limit do
table.remove( result )
end
end
return result
end
---Функция для получения значения свойства элемента в заданный момент времени.
---@param entityId string
---@param boundaries table Временные границы
---@param propertyIds table<string>
---@param selectors table<string>
---@return table Таблица соответствующих значений свойства
local function getPropertyInBoundaries( context, entityId, boundaries, propertyIds, selectors )
if type( entityId ) ~= 'string' then error( 'type of entityId argument expected string, but was ' .. type(entityId)); end
local results = {}
if not propertyIds or #propertyIds == 0 then
return results
end
for i, propertyId in ipairs( propertyIds ) do
local selector
if selectors ~= nil then
selector = selectors[ i ] or selectors[ propertyId ] or propertyId
else
selector = propertyId
end
local fakeAllClaims = {}
fakeAllClaims[ propertyId ] = mw.wikibase.getAllStatements( entityId, propertyId )
local filteredClaims = WDS.filter( fakeAllClaims, selector .. '[rank:preferred, rank:normal]' )
if filteredClaims then
for _, claim in pairs( filteredClaims ) do
if not boundaries then
if not claim.qualifiers or not claim.qualifiers.P582 then
table.insert( results, claim.mainsnak )
end
else
local startBoundaries = p.getTimeBoundariesFromQualifier( context.frame, context, claim, 'P580' )
local endBoundaries = p.getTimeBoundariesFromQualifier( context.frame, context, claim, 'P582' )
if ( startBoundaries == nil or startBoundaries[ 1 ] <= boundaries[ 1 ] ) and
( endBoundaries == nil or endBoundaries[ 1 ] >= boundaries[ 2 ] )
then
table.insert( results, claim.mainsnak )
end
end
end
end
if #results > 0 then
break
end
end
return results
end
---@param context table
---@param propertyId string
---@return table | nil
function p.getTimeBoundariesFromProperty( context, propertyId )
local dateClaims = WDS.filter( context.entity.claims, propertyId )
if not dateClaims or #dateClaims == 0 then
return nil;
end
-- only support exact date so far, but need improvment
local left = nil
local right = nil
for _, claim in pairs( dateClaims ) do
if not claim.mainsnak then
return nil
end
local boundaries = context.parseTimeBoundariesFromSnak( claim.mainsnak )
if not boundaries then
return nil
end
left = min( left, boundaries[ 1 ] )
right = max( right, boundaries[ 2 ] )
end
if not left or not right then
return nil
end
return { left, right }
end
---@param context table
---@param propertyIds table<string>
---@return table | nil
function p.getTimeBoundariesFromProperties( context, propertyIds )
for _, propertyId in ipairs( propertyIds ) do
local result = p.getTimeBoundariesFromProperty( context, propertyId );
if result then
return result
end
end
return nil
end
---@param context table
---@param statement table
---@param qualifierId string
---@return table | nil
function p.getTimeBoundariesFromQualifier( _, context, statement, qualifierId )
-- only support exact date so far, but need improvement
local left, right
if statement.qualifiers and statement.qualifiers[ qualifierId ] then
for _, qualifier in pairs( statement.qualifiers[ qualifierId ] ) do
local boundaries = context.parseTimeBoundariesFromSnak( qualifier )
if not boundaries then
return nil
end
left = min( left, boundaries[ 1 ] )
right = max( right, boundaries[ 2 ] )
end
end
if not left or not right then
return nil
end
return { left, right }
end
---@param _ table
---@param context table
---@param statement table
---@param qualifierIds table<string>
---@return table | nil
function p.getTimeBoundariesFromQualifiers( _, context, statement, qualifierIds )
if not qualifierIds then
qualifierIds = { 'P582', 'P580', 'P585' }
end
for _, qualifierId in pairs( qualifierIds ) do
local result = p.getTimeBoundariesFromQualifier( _, context, statement, qualifierId )
if result then
return result
end
end
return nil
end
---@type table<string>
local getLabelWithLang_DEFAULT_PROPERTIES = { 'P1813', 'P1448', 'P1705' }
---@type table<string>
local getLabelWithLang_DEFAULT_SELECTORS = {
'P1813[language:' .. CONTENT_LANGUAGE_CODE .. '][!P282,P282:' .. writingSystemElementId .. '][!P3831,P3831:Q105690470]',
'P1448[language:' .. CONTENT_LANGUAGE_CODE .. '][!P282,P282:' .. writingSystemElementId .. '][!P3831,P3831:Q105690470]',
'P1705[language:' .. CONTENT_LANGUAGE_CODE .. '][!P282,P282:' .. writingSystemElementId .. '][!P3831,P3831:Q105690470]'
}
---Функция для получения метки элемента в заданный момент времени.
---@param context table
---@param options table
---@param entityId string
---@param boundaries table
---@param propertyIds table
---@param selectors table<string>
---@return string, string Текстовая метка элемента, язык метки
local function getLabelWithLang( context, options, entityId, boundaries, propertyIds, selectors )
if type( entityId ) ~= 'string' then error( 'type of entityId argument expected string, but was ' .. type( entityId ) ); end
if not entityId then
return nil
end
local langCode = CONTENT_LANGUAGE_CODE
-- name from label
local label
if options.text and options.text ~= '' then
label = options.text
else
if not propertyIds then
propertyIds = getLabelWithLang_DEFAULT_PROPERTIES
selectors = getLabelWithLang_DEFAULT_SELECTORS
end
-- name from properties
local results = getPropertyInBoundaries( context, entityId, boundaries, propertyIds, selectors )
for _, result in pairs( results ) do
if result.datavalue and result.datavalue.value then
if result.datavalue.type == 'monolingualtext' and result.datavalue.value.text then
label = result.datavalue.value.text
langCode = result.datavalue.value.language
break
elseif result.datavalue.type == 'string' then
label = result.datavalue.value
break
end
end
end
if not label then
label, langCode = mw.wikibase.getLabelWithLang( entityId )
if not langCode then
return nil
end
end
end
return label, langCode
end
---@param context table
---@param options table
---@return string
local function formatPropertyDefault( context, options )
if not context then error( 'context not specified' ); end
if not options then error( 'options not specified' ); end
if not options.entityId then error( 'options.entityId missing' ); end
local claims
if options.property then -- TODO: Почему тут может не быть property?
if options.rank then -- передать настройки ранга из конфига
claims = context.selectClaims( options, options.property .. options.rank )
else
claims = context.selectClaims( options, options.property )
end
end
if claims == nil then
return '' --TODO error?
end
-- Обход всех заявлений утверждения и с накоплением оформленных предпочтительных
-- заявлений в таблице
local formattedClaims = {}
for _, claim in pairs( claims ) do
local formattedStatement = context.formatStatement( options, claim )
-- здесь может вернуться либо оформленный текст заявления, либо строка ошибки, либо nil
if formattedStatement and formattedStatement ~= '' then
if not options.plain then
formattedStatement = context.wrapStatement( formattedStatement, options.property, claim.id )
end
table.insert( formattedClaims, formattedStatement )
end
end
-- создание текстовой строки со списком оформленых заявлений из таблицы
local out = mw.text.listToText( formattedClaims, options.separator, options.conjunction )
if out ~= '' then
if options.before then
out = options.before .. out
end
if options.after then
out = out .. options.after
end
end
return out
end
---Create context
---@param initOptions table
---@return table | nil
local function initContext( initOptions )
local context = {
entityId = initOptions.entityId,
entity = initOptions.entity,
extractCategory = extractCategory,
formatSnak = formatSnak,
formatPropertyDefault = formatPropertyDefault,
formatStatementDefault = formatStatementDefault,
getPropertyInBoundaries = getPropertyInBoundaries,
getTimeBoundariesFromProperty = p.getTimeBoundariesFromProperty,
getTimeBoundariesFromProperties = p.getTimeBoundariesFromProperties,
getTimeBoundariesFromQualifier = p.getTimeBoundariesFromQualifier,
getTimeBoundariesFromQualifiers = p.getTimeBoundariesFromQualifiers,
parseTimeFromSnak = p._parseTimeFromSnak,
getLabelWithLang = getLabelWithLang,
wrapSnak = wrapSnak,
wrapStatement = wrapStatement,
wrapQualifier = wrapQualifier,
}
context.cloneOptions = function( options )
local entity = options.entity
options.entity = nil
local newOptions = mw.clone( options )
options.entity = entity
newOptions.entity = entity
newOptions.frame = options.frame; -- На склонированном фрейме frame:expandTemplate()
return newOptions
end
context.formatProperty = function( options )
local func = getUserFunction( options, 'property', context.formatPropertyDefault )
return func( context, options )
end
context.formatStatement = function( options, statement ) return formatStatement( context, options, statement ) end
context.formatSnak = function( options, snak, circumstances ) return formatSnak( context, options, snak, circumstances ) end
context.formatRefs = function( options, statement ) return formatRefs( context, options, statement ) end
context.parseTimeBoundariesFromSnak = function( snak )
if snak and snak.datavalue and snak.datavalue.value and snak.datavalue.value.time and snak.datavalue.value.precision then
return p._parseTimeBoundaries( snak.datavalue.value.time, snak.datavalue.value.precision )
end
return nil
end
context.getSourcingCircumstances = function( statement )
return getSourcingCircumstances( statement )
end
context.selectClaims = function( options, propertyId )
return selectClaims( context, options, propertyId )
end
return context
end
---Функция для оформления утверждений (statement)
---Подробнее о утверждениях см. d:Wikidata:Glossary/ru
---@param options table
---@return string Formatted wikitext.
local function formatProperty( options )
-- Получение сущности по идентификатору
local entity = getEntityFromId( options.entityId )
if not entity then
return -- throwError( 'entity-not-found' )
end
-- проверка на присутсвие у сущности заявлений (claim)
-- подробнее о заявлениях см. d:Викиданные:Глоссарий
if not entity.claims then
return '' --TODO error?
end
-- improve options
options.frame = g_frame
options.entity = entity
options.extends = function( self, newOptions )
return copyTo( newOptions, copyTo( self, {} ) )
end
if options.i18n then
options.i18n = copyTo( options.i18n, copyTo( getConfig( 'i18n' ), {} ) )
else
options.i18n = getConfig( 'i18n' )
end
local context = initContext( options )
return context.formatProperty( options )
end
---Функция для оформления одного утверждения (statement)
---@param context table
---@param options table
---@param statement table
---@return string Formatted wikitext.
function formatStatement( context, options, statement )
if not statement then
error( 'statement is not specified or nil' )
end
if not statement.type or statement.type ~= 'statement' then
throwError( 'unknown-claim-type' )
end
local functionToCall = getUserFunction( options, 'claim', context.formatStatementDefault )
return functionToCall( context, options, statement )
end
---@param statement table
---@return table
function getSourcingCircumstances( statement )
if not statement then
error( 'statement is not specified' )
end
local circumstances = {}
if statement.qualifiers and statement.qualifiers.P1480 then
for _, qualifier in pairs( statement.qualifiers.P1480 ) do
if qualifier
and qualifier.datavalue
and qualifier.datavalue.type == 'wikibase-entityid'
and qualifier.datavalue.value
and qualifier.datavalue.value[ 'entity-type'] == 'item'
then
table.insert( circumstances, qualifier.datavalue.value.id )
end
end
end
return circumstances
end
---Функция для оформления одного утверждения (statement)
---@param context table Context.
---@param options table Parameters.
---@param statement table
---@return string Formatted wikitext.
function formatStatementDefault( context, options, statement )
if not context then error( 'context is not specified' ) end
if not options then error( 'options is not specified' ) end
if not statement then error( 'statement is not specified' ) end
local circumstances = context.getSourcingCircumstances( statement )
options.qualifiers = statement.qualifiers
local result = context.formatSnak( options, statement.mainsnak, circumstances )
if options.qualifier and statement.qualifiers and statement.qualifiers[ options.qualifier ] then
local qualifierConfig = getPropertyParams( options.qualifier, nil, {} )
if options.i18n then
qualifierConfig.i18n = options.i18n
end
if qualifierConfig.datatype == 'time' then
qualifierConfig.nolinks = true
end
local qualifierValues = {}
for _, qualifierSnak in pairs( statement.qualifiers[ options.qualifier ] ) do
local snakValue = context.formatSnak( qualifierConfig, qualifierSnak )
if snakValue and snakValue ~= '' then
table.insert( qualifierValues, snakValue )
end
end
if result and result ~= '' and #qualifierValues then
if qualifierConfig.invisible then
result = result .. table.concat( qualifierValues, ', ' )
else
result = result .. ' (' .. table.concat( qualifierValues, ', ' ) .. ')'
end
end
end
if result and result ~= '' and options.references then
result = result .. context.formatRefs( options, statement )
end
return result
end
---Функция для оформления части утверждения (snak)
---Подробнее о snak см. d:Викиданные:Глоссарий
---@param context table Context.
---@param options table Parameters.
---@param snak table
---@param circumstances table
---@return string Formatted wikitext.
function formatSnak( context, options, snak, circumstances )
circumstances = circumstances or {}
local result
if snak.snaktype == 'somevalue' then
if options[ 'somevalue' ] and options[ 'somevalue' ] ~= '' then
result = options[ 'somevalue' ]
else
result = options.i18n[ 'somevalue' ]
end
elseif snak.snaktype == 'novalue' then
if options[ 'novalue' ] and options[ 'novalue' ] ~= '' then
result = options[ 'novalue' ]
else
result = options.i18n[ 'novalue' ]
end
elseif snak.snaktype == 'value' then
result = formatDatavalue( context, options, snak.datavalue, snak.datatype )
for _, item in pairs( circumstances ) do
if options.i18n[ item ] then
result = options.i18n[ item ] .. result
end
end
else
throwError( 'unknown-snak-type' )
end
if not result or result == '' then
return nil
end
if options.plain then
return result
end
return context.wrapSnak( result, snak.hash )
end
---Функция для оформления объектов-значений с географическими координатами
---@param value string Raw value.
---@param options table Parameters.
---@return string Formatted string.
local function formatGlobeCoordinate( value, options )
-- проверка на требование в параметрах вызова на возврат сырого значения
if options[ 'subvalue' ] == 'latitude' then -- широты
return value[ 'latitude' ]
elseif options[ 'subvalue' ] == 'longitude' then -- долготы
return value[ 'longitude' ]
elseif options[ 'nocoord' ] and options[ 'nocoord' ] ~= '' then
-- если передан параметр nocoord, то не выводить координаты
-- обычно это делается при использовании нескольких карточек на странице
return ''
else
-- в противном случае формируются параметры для вызова шаблона {{coord}}
-- нужно дописать в документации шаблона, что он отсюда вызывается, и что
-- любое изменние его парамеров должно быть согласовано с кодом тут
local coordModule = require( 'Module:Coordinates' )
local globe = options.globe or ''
if globe == '' and value[ 'globe' ] then
local globes = require( 'Module:Wikidata/Globes' )
globe = globes[ value[ 'globe' ] ] or ''
end
local display = 'inline'
if options.display and options.display ~= '' then
display = options.display
elseif ( options.property:upper() == 'P625' ) then
display = 'title'
end
local format = options.format or ''
if format == '' then
format = 'dms'
if value[ 'precision' ] then
local precision = value[ 'precision' ] * 60
if precision >= 60 then
format = 'd'
elseif precision >= 1 then
format = 'dm'
end
end
end
g_frame.args = {
tostring( value[ 'latitude' ] ),
tostring( value[ 'longitude' ] ),
globe = globe,
type = options.type and options.type or '',
scale = options.scale and options.scale or '',
display = display,
format = format,
}
return coordModule.coord(g_frame)
end
end
---Функция для оформления объектов-значений с файлами с Викисклада
---@param value string Raw value.
---@param options table Parameters.
---@return string Formatted string.
local function formatCommonsMedia( value, options )
local image = value
local caption = ''
if options[ 'caption' ] and options[ 'caption' ] ~= '' then
caption = options[ 'caption' ]
end
if caption ~= '' then
caption = wrapQualifier( caption, 'P2096', { class = 'media-caption', style = 'display:block' } )
end
if not string.find( value, '[%[%]%{%}]' ) and not string.find( value, 'UNIQ%-%-imagemap' ) then
-- если в value не содержится викикод или imagemap, то викифицируем имя файла
-- ищем слово imagemap в строке, потому что вставляется плейсхолдер: [[phab:T28213]]
image = '[[File:' .. value .. '|frameless'
if options[ 'border' ] and options[ 'border' ] ~= '' then
image = image .. '|border'
end
local size = options[ 'size' ]
if size and size ~= '' then
-- TODO: check localized pixel names too
if not string.match( size, 'px$' ) then
size = size .. 'px'
end
else
size = fileDefaultSize
end
image = image .. '|' .. size
if options[ 'alt' ] and options[ 'alt' ] ~= '' then
image = image .. '|alt=' .. options[ 'alt' ]
end
if caption ~= '' then
image = image .. '|' .. caption
end
image = image .. ']]'
if caption ~= '' then
image = image .. '<br>' .. caption
end
else
image = image .. caption .. getCategoryByCode( 'media-contains-markup' )
end
return image
end
---Function for render math formulas
---@param value string Value.
---@param options table Parameters.
---@return string Formatted string.
local function formatMath( value, options )
return options.frame:extensionTag{ name = 'math', content = value }
end
---Функция для оформления внешних идентификаторов
---@param value string
---@param options table
---@return string
local function formatExternalId( value, options )
local formatter = options.formatter
local propertyId = options.property:upper()
if not formatter or formatter == '' then
local isGoodFormat = false
local wbStatus, formatRegexStatements = pcall( mw.wikibase.getBestStatements, propertyId, 'P1793' )
if wbStatus and formatRegexStatements then
for _, statement in pairs( formatRegexStatements ) do
if statement.mainsnak.snaktype == 'value' then
local pattern = mw.ustring.gsub( statement.mainsnak.datavalue.value, '\\', '%' )
pattern = mw.ustring.gsub( pattern, '{%d+,?%d*}', '+' )
if ( string.find( pattern, '|' ) or string.find( pattern, '%)%?' )
or mw.ustring.match( value, '^' .. pattern .. '$' ) ~= nil ) then
isGoodFormat = true
break
end
end
end
end
if isGoodFormat then
local formatterStatements
wbStatus, formatterStatements = pcall( mw.wikibase.getBestStatements, propertyId, 'P1630' )
if wbStatus and formatterStatements then
for _, statement in pairs( formatterStatements ) do
if statement.mainsnak.snaktype == 'value' then
formatter = statement.mainsnak.datavalue.value
break
end
end
end
end
end
if formatter and formatter ~= '' then
local encodedValue = mw.ustring.gsub( value, '%%', '%%%%' ) -- ломается, если подставить внутрь другого mw.ustring.gsub
local link = mw.ustring.gsub(
mw.ustring.gsub( formatter, '$1', encodedValue ), '.',
{ [ ' ' ] = '%20', [ '+' ] = '%2b', [ '[' ] = '%5B', [ ']' ] = '%5D' } )
local title = options.title
if not title or title == '' then
title = '$1'
end
title = mw.ustring.gsub(
mw.ustring.gsub( title, '$1', encodedValue ), '.',
{ [ '[' ] = '(', [ ']' ] = ')' } )
return '[' .. link .. ' ' .. title .. ']'
end
return value
end
---Функция для оформления числовых значений
---@param value table Объект-значение
---@param options table Таблица параметров
---@return string Оформленный текст
local function formatQuantity( value, options )
-- диапазон значений
local amount = string.gsub( value.amount, '^%+', '' )
local lang = mw.language.getContentLanguage()
local langCode = lang:getCode()
local function formatNum( number, sigfig )
local multiplier = ''
if options.countByThousands then
local powers = options.i18n.thousandPowers
local pos = 1
while math.abs( number ) >= 1000 and pos < #powers do
number = number / 1000
pos = pos + 1
end
multiplier = powers[ pos ]
if math.abs( number ) >= 100 then
sigfig = sigfig or 0
elseif math.abs( number ) >= 10 then
sigfig = sigfig or 1
else
sigfig = sigfig or 2
end
else
sigfig = sigfig or 12 -- округление до 12 знаков после запятой, на 13-м возникает ошибка в точности
end
local iMultiplier = 10^sigfig
number = math.floor( number * iMultiplier + 0.5 ) / iMultiplier
return string.gsub( lang:formatNum( number ), '^-', '−' ) .. multiplier
end
local out = formatNum( tonumber( amount ) )
if value.upperBound then
local diff = tonumber( value.upperBound ) - tonumber( amount )
if diff > 0 then -- временная провека, пока у большинства значений не будет убрано ±0
-- Пробуем понять до какого знака округлять
local integer, dot, decimals, _ = value.upperBound:match( '^+?-?(%d*)(%.?)(%d*)(.*)' )
local precision
if dot == '' then
precision = -integer:match( '0*$' ):len()
else
precision = #decimals
end
local bound = formatNum( diff, precision )
if string.match( bound, 'E%-(%d+)' ) then -- если в экспоненциальном формате
local digits = tonumber( string.match( bound, 'E%-(%d+)' ) ) - 2
bound = formatNum( diff * 10 ^ digits, precision )
bound = string.sub( bound, 0, 2 ) .. string.rep( '0', digits ) .. string.sub( bound, -string.len( bound ) + 2 )
end
out = out .. ' ± ' .. bound
end
end
if options.unit and options.unit ~= '' then
if options.unit ~= '-' then
out = out .. ' ' .. options.unit
end
elseif value.unit and string.match( value.unit, 'http://www.wikidata.org/entity/' ) then
local unitEntityId = string.gsub( value.unit, 'http://www.wikidata.org/entity/', '' )
if unitEntityId ~= 'undefined' then
local wbStatus, unitEntity = pcall( mw.wikibase.getEntity, unitEntityId )
if wbStatus == true and unitEntity then
if unitEntity.claims.P2370 and
unitEntity.claims.P2370[ 1 ].mainsnak.snaktype == 'value' and
not value.upperBound and
options.siConversion == true
then
local conversionToSiUnit = string.gsub( unitEntity.claims.P2370[ 1 ].mainsnak.datavalue.value.amount, '^%+', '' )
if math.floor( math.log10( conversionToSiUnit ) ) ~= math.log10( conversionToSiUnit ) then
-- Если не степени десятки (переводить сантиметры в метры не надо!)
local outValue = tonumber( amount ) * conversionToSiUnit
if outValue > 0 then
-- Пробуем понять до какого знака округлять
local integer, dot, decimals, _ = amount:match( '^(%d*)(%.?)(%d*)(.*)' )
local precision
if dot == '' then
precision = -integer:match( '0*$' ):len()
else
precision = #decimals
end
local adjust = math.log10( math.abs( conversionToSiUnit ) ) + math.log10( 2 )
local minPrecision = 1 - math.floor( math.log10( outValue ) + 2e-14 )
out = formatNum( outValue, math.max( math.floor( precision + adjust ), minPrecision ) )
else
out = formatNum( outValue, 0 )
end
unitEntityId = string.gsub( unitEntity.claims.P2370[ 1 ].mainsnak.datavalue.value.unit, 'http://www.wikidata.org/entity/', '' )
wbStatus, unitEntity = pcall( mw.wikibase.getEntity, unitEntityId )
end
end
local label = getLabelWithLang( context, options, unitEntity.id, nil, { "P5061", "P558", "P558" }, {
'P5061[language:' .. langCode .. ']',
'P558[P282:' .. writingSystemElementId .. ', P407:' .. langElementId .. ']',
'P558[!P282][!P407]'
} )
out = out .. ' ' .. label
end
end
end
return out
end
---Функция для оформления URL
---@param context table
---@param options table
---@param value string
local function formatUrlValue( context, options, value )
if not options.length or options.length == '' then
options.length = 25
end
local moduleUrl = require( 'Module:URL' )
return moduleUrl.formatUrlSingle( context, options, value )
end
local DATATYPE_CACHE = {}
---Get property datatype by ID.
---@param propertyId string Property ID, e.g. 'P123'.
---@return string Property datatype, e.g. 'commonsMedia', 'time' or 'url'.
local function getPropertyDatatype( propertyId )
if not propertyId or not string.match( propertyId, '^P%d+$' ) then
return nil
end
local cached = DATATYPE_CACHE[ propertyId ]
if cached ~= nil then
return cached
end
local wbStatus, propertyEntity = pcall( mw.wikibase.getEntity, propertyId )
if wbStatus ~= true or not propertyEntity then
return nil
end
mw.log("Loaded datatype " .. propertyEntity.datatype .. " of " .. propertyId .. ' from wikidata, consider passing datatype argument to formatProperty call or to Wikidata/config' )
DATATYPE_CACHE[ propertyId ] = propertyEntity.datatype
return propertyEntity.datatype
end
---@param datavalue table
---@return function
local function getPlainValueFunction( datavalue, _ )
if datavalue.type == 'wikibase-entityid' then
return function( _, _, value )
return getEntityIdFromValue( value )
end
elseif datavalue.type == 'string' then
return function( _, _, value )
return value
end
elseif datavalue.type == 'monolingualtext' then
return function( _, _, value )
return value.text
end
elseif datavalue.type == 'globecoordinate' then
return function( _, _, value )
return value.latitude .. ',' .. value.longitude
end
elseif datavalue.type == 'quantity' then
return function( _, _, value )
return value.amount
end
elseif datavalue.type == 'time' then
return function( _, _, value )
return value.time
end
end
throwError( 'unknown-datavalue-type' )
end
---@param datavalue table
---@param datatype string
---@return function
local function getDefaultValueFunction( datavalue, datatype )
-- вызов обработчиков по умолчанию для известных типов значений
if datavalue.type == 'wikibase-entityid' then
-- Entity ID
return function( context, options, value )
return formatEntityId( context, options, getEntityIdFromValue( value ) )
end
elseif datavalue.type == 'string' then
-- String
if datatype and datatype == 'commonsMedia' then
-- Media
return function( _, options, value )
return formatCommonsMedia( value, options )
end
elseif datatype and datatype == 'external-id' then
-- External ID
return function( _, options, value )
return formatExternalId( value, options )
end
elseif datatype and datatype == 'math' then
-- Math formula
return function( _, options, value )
return formatMath( value, options )
end
elseif datatype and datatype == 'url' then
-- URL
return formatUrlValue
end
return function( _, _, value )
return value
end
elseif datavalue.type == 'monolingualtext' then
-- моноязычный текст (строка с указанием языка)
return function( _, options, value )
if options.monolingualLangTemplate == 'lang' then
if value.language == CONTENT_LANGUAGE_CODE then
return value.text
end
return options.frame:expandTemplate{ title = 'lang-' .. value.language, args = { value.text } }
elseif options.monolingualLangTemplate == 'ref' then
return '<span class="lang" lang="' .. value.language .. '">' .. value.text .. '</span>' .. options.frame:expandTemplate{ title = 'ref-' .. value.language }
else
return '<span class="lang" lang="' .. value.language .. '">' .. value.text .. '</span>'
end
end
elseif datavalue.type == 'globecoordinate' then
-- географические координаты
return function( _, options, value )
return formatGlobeCoordinate( value, options )
end
elseif datavalue.type == 'quantity' then
return function( _, options, value )
return formatQuantity( value, options )
end
elseif datavalue.type == 'time' then
return function( context, options, value )
local moduleDate = require( 'Module:Wikidata/date' )
return moduleDate.formatDate( context, options, value )
end
end
-- во всех стальных случаях возвращаем ошибку
throwError( 'unknown-datavalue-type' )
end
---Функция для оформления значений (value)
---Подробнее о значениях см. d:Wikidata:Glossary/ru
---@param context table
---@param options table
---@param datavalue table
---@param datatype string
---@return string Оформленный текст
function formatDatavalue( context, options, datavalue, datatype )
if not context then error( 'context not specified' ); end
if not options then error( 'options not specified' ); end
if not datavalue then error( 'datavalue not specified' ); end
if not datavalue.value then error( 'datavalue.value is missing' ); end
-- проверка на указание специализированных обработчиков в параметрах,
-- переданных при вызове
if options.plain then
context.formatValueDefault = getPlainValueFunction( datavalue, datatype )
else
context.formatValueDefault = getDefaultValueFunction( datavalue, datatype )
end
local functionToCall = getUserFunction( options, 'value', context.formatValueDefault )
return functionToCall( context, options, datavalue.value )
end
local DEFAULT_BOUNDARIES = { os.time() * 1000, os.time() * 1000}
---Функция для оформления идентификатора сущности
---@param context table
---@param options table
---@param entityId string
---@return string Оформленный текст
function formatEntityId( context, options, entityId )
-- получение локализованного названия
local boundaries
if options.qualifiers then
boundaries = p.getTimeBoundariesFromQualifiers( context.frame, context, { qualifiers = options.qualifiers } )
end
if not boundaries then
boundaries = DEFAULT_BOUNDARIES
end
local label, labelLanguageCode = getLabelWithLang( context, options, entityId, boundaries )
-- определение соответствующей показываемому элементу категории
local category = context.extractCategory( options, { id = entityId } )
-- получение ссылки по идентификатору
local link = mw.wikibase.sitelink( entityId )
if link then
-- ссылка на категорию, а не добавление страницы в неё
if mw.ustring.match( link, '^' .. mw.site.namespaces[ 14 ].name .. ':' ) then
link = ':' .. link
end
if label and not options.rawArticle then
if labelLanguageCode ~= CONTENT_LANGUAGE_CODE then
label = '<span lang="' .. label .. '">' .. label .. '</span>'
end
local a = '[[' .. link .. '|' .. label .. ']]'
if CONTENT_LANGUAGE_CODE ~= labelLanguageCode and 'mul' ~= labelLanguageCode then
a = a .. getCategoryByCode( 'links-to-entities-with-missing-local-language-label' )
end
return a .. category
else
return '[[' .. link .. ']]' .. category
end
end
if label then -- TODO: возможно, лучше просто mw.wikibase.getLabel(entityId)
-- красная ссылка
-- TODO: разобраться, почему не всегда есть options.frame
local moduleRedLink = require( 'Module:Wikidata/redLink' )
local title = mw.title.new( label )
if title and not title.exists and options.frame then
local rawLabel = mw.wikibase.getLabel(entityId) or label -- без |text= и boundaries; or label - костыль
local redLink = moduleRedLink.formatRedLinkWithInfobox(rawLabel, label, entityId)
if CONTENT_LANGUAGE_CODE ~= labelLanguageCode and 'mul' ~= labelLanguageCode then
redLink = '<span lang="' .. labelLanguageCode .. '">' .. redLink .. '</span>' ..
getCategoryByCode( 'links-to-entities-with-missing-local-language-label' )
end
return redLink .. category
end
-- TODO: перенести до проверки на существование статьи
local addWdLink = false
if ( not options.format or options.format ~= 'text' )
and entityId ~= 'Q6581072' and entityId ~= 'Q6581097' -- TODO: переписать на format=text
then
addWdLink = true
end
-- одноимённая статья уже существует - выводится текст и ссылка на ВД
return moduleRedLink.formatText(label, entityId, addWdLink) .. category
end
-- сообщение об отсутвии локализованного названия
-- not good, but better than nothing
return '[[:d:' .. entityId .. '|' .. entityId .. ']]<span style="border-bottom: 1px dotted; cursor: help; white-space: nowrap" title="В Викиданных нет русской подписи к элементу. Вы можете помочь, указав русский вариант подписи.">?</span>' .. getCategoryByCode( 'links-to-entities-with-missing-label' ) .. category
end
---Функция для оформления утверждений (statement)
---Подробнее о утверждениях см. d:Wikidata:Glossary/ru
---@deprecated Use p.formatProperty() instead
---@param frame table
---@return string Строка оформленного текста, предназначенная для отображения в статье
function p.formatStatements( frame )
return p.formatProperty( frame )
end
---Получение параметров, которые обычно используются для вывода свойства.
---@param propertyId string
---@param datatype string
---@param params table
function getPropertyParams( propertyId, datatype, params )
local config = getConfig()
-- Различные уровни настройки параметров, по убыванию приоритета
local propertyParams = {}
-- 1. Параметры, указанные явно при вызове
if params then
for key, value in pairs( params ) do
if value ~= '' then
propertyParams[ key ] = value
end
end
end
if toBoolean( propertyParams.plain, false ) then
propertyParams.separator = propertyParams.separator or ', '
propertyParams.conjunction = propertyParams.conjunction or ', '
else
-- 2. Настройки конкретного параметра
if config.properties and config.properties[ propertyId ] then
for key, value in pairs( config.properties[ propertyId ] ) do
if propertyParams[ key ] == nil then
propertyParams[ key ] = value
end
end
end
-- 3. Указанный пресет настроек
if propertyParams.preset and config.presets and
config.presets[ propertyParams.preset ]
then
for key, value in pairs( config.presets[ propertyParams.preset ] ) do
if propertyParams[ key ] == nil then
propertyParams[ key ] = value
end
end
end
datatype = datatype or params.datatype or propertyParams.datatype or getPropertyDatatype( propertyId )
if propertyParams.datatype == nil then
propertyParams.datatype = datatype
end
-- 4. Настройки для типа данных
if datatype and config.datatypes and config.datatypes[ datatype ] then
for key, value in pairs( config.datatypes[ datatype ] ) do
if propertyParams[ key ] == nil then
propertyParams[ key ] = value
end
end
end
-- 5. Общие настройки для всех свойств
if config.global then
for key, value in pairs( config.global ) do
if propertyParams[ key ] == nil then
propertyParams[ key ] = value
end
end
end
end
return propertyParams
end
---Функция для оформления утверждений (statement)
---Подробнее о утверждениях см. d:Wikidata:Glossary/ru
---@param frame table
---@return string Строка оформленного текста, предназначенная для отображения в статье
function p.formatProperty( frame )
local args = copyTo( frame.args, {} )
-- проверка на отсутствие обязательного параметра property
if not args.property then
throwError( 'property-param-not-provided' )
end
local override
local propertyId = mw.language.getContentLanguage():ucfirst( string.gsub( args.property, '([^Pp0-9].*)$', function(w)
if string.sub( w, 1, 1 ) == '~' then
override = w
end
return ''
end ) )
if override then
args[ override:match( '[,~]([^=]*)=' ) ] = override:match( '=(.*)' )
args.property = propertyId
end
-- проброс всех параметров из шаблона {wikidata} и параметра from откуда угодно
local p_frame = frame
while p_frame do
if p_frame:getTitle() == mw.site.namespaces[ 10 ].name .. ':Wikidata' then
copyTo( p_frame.args, args, true )
end
if p_frame.args and p_frame.args.from and p_frame.args.from ~= '' then
args.entityId = p_frame.args.from
else
args.entityId = mw.wikibase.getEntityIdForCurrentPage()
end
p_frame = p_frame:getParent()
end
args = getPropertyParams( propertyId, nil, args )
local datatype = args.datatype
-- перевод итоговых значений флагов в true/false и добавление значений
-- по умолчанию только в том случае, если они нигде не были указаны ранее
args.plain = toBoolean( args.plain, false )
args.nocat = not args.plain and toBoolean( args.nocat, false )
args.references = not args.plain and toBoolean( args.references, true )
-- если значение передано в параметрах вызова то выводим только его
if args.value and args.value ~= '' then
-- специальное значение для скрытия Викиданных
if args.value == '-' then
return ''
end
local value = args.value
-- опция, запрещающая оформление значения, поэтому никак не трогаем
if args.plain then
return value
end
local context = initContext( args )
-- обработчики по типу значения
local wrapperExtraArgs = {}
if args[ 'value-module' ] and args[ 'value-function' ] and not string.find( value, '[%[%]%{%}]' ) then
local func = getUserFunction( args, 'value' )
value = func( context, args, value )
elseif datatype == 'commonsMedia' then
value = formatCommonsMedia( value, args )
elseif datatype == 'external-id' and not string.find( value, '[%[%]%{%}]' ) then
wrapperExtraArgs[ 'data-wikidata-external-id' ] = mw.text.killMarkers( value )
value = formatExternalId( value, args )
--elseif datatype == 'math' then
-- args.frame = frame -- костыль: в formatMath нужно frame:extensionTag
-- value = formatMath( value, args )
elseif datatype == 'url' then
value = formatUrlValue( context, args, value )
end
-- оборачиваем в тег для JS-функций
if string.match( propertyId, '^P%d+$' ) then
value = mw.text.trim( value )
-- временная штрафная категория для исправления табличных вставок
local allowTables = getPropertyParams( propertyId, nil, {} ).allowTables
if not allowTables
and string.match( value, '<t[dhr][ >]' )
-- and not string.match( value, '<table[ >]' )
-- and not string.match( value, '^%{%|' )
then
value = value .. getCategoryByCode( 'value-contains-table', propertyId )
else
value = wrapStatement( value, propertyId, nil, wrapperExtraArgs )
end
end
return value
end
-- ability to disable loading Wikidata
if args.entityId == '-' then
return ''
end
g_frame = frame
-- после проверки всех аргументов -- вызов функции оформления для свойства (набора утверждений)
return formatProperty( args )
end
---Функция проверки на присутствие источника в списке нерекомендованных.
---@param snaks table
---@return boolean
local function isReferenceDeprecated( snaks )
if not snaks then
return false
end
if snaks.P248
and snaks.P248[ 1 ]
and snaks.P248[ 1 ].datavalue
and snaks.P248[ 1 ].datavalue.value.id
then
local entityId = snaks.P248[ 1 ].datavalue.value.id
if getConfig( 'deprecatedSources', entityId ) then
return true
end
elseif snaks.P1433
and snaks.P1433[ 1 ]
and snaks.P1433[ 1 ].datavalue
and snaks.P1433[ 1 ].datavalue.value.id
then
local entityId = snaks.P1433[ 1 ].datavalue.value.id
if getConfig( 'deprecatedSources', entityId ) then
return true
end
end
return false
end
---Функция оформления ссылок на источники (reference)
---Подробнее о ссылках на источники см. d:Wikidata:Glossary/ru
---
---Экспортируется в качестве зарезервированной точки для вызова из функций-расширения вида claim-module/claim-function через context
---Вызов из других модулей напрямую осуществляться не должен (используйте frame:expandTemplate вместе с одним из специлизированных шаблонов вывода значения свойства).
---@param context table
---@param options table
---@param statement table
---@return string Оформленные примечания для отображения в статье
function formatRefs( context, options, statement )
if not context then error( 'context not specified' ); end
if not options then error( 'options not specified' ); end
if not options.entityId then error( 'options.entityId missing' ); end
if not statement then error( 'statement not specified' ); end
if not outputReferences then
return ''
end
---@type string[]
local references = {}
if statement.references then
local hasNotDeprecated = false
local displayCount = 0
for _, reference in pairs( statement.references ) do
if not isReferenceDeprecated( reference.snaks ) then
hasNotDeprecated = true
end
end
for _, reference in pairs( statement.references ) do
local display = true
if hasNotDeprecated then
if isReferenceDeprecated( reference.snaks ) then
display = false
end
end
if displayCount >= 2 then
if options.entityId and options.property then
local propertyId = mw.ustring.match( options.property, '^[Pp][0-9]+' ) -- TODO: обрабатывать не тут, а раньше
local moreReferences = '<sup>[[d:' .. options.entityId .. '#' .. string.upper( propertyId ) .. '|[…]]]</sup>'
table.insert( references, moreReferences )
end
break
end
if display == true then
---@type string
local refText = moduleSources.renderReference( g_frame, options.entityId, reference )
if refText and refText ~= '' then
table.insert( references, refText )
displayCount = displayCount + 1
end
end
end
end
return table.concat( references )
end
return p
4558f762f30c6ebfb9f5333dbd7ebda83c6873f2
Шаблон:Delink
10
263
688
687
2024-08-26T16:45:47Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{<includeonly>safesubst:</includeonly>#invoke:delink|delink}}<noinclude>
{{doc}}
</noinclude>
dbac86e53b946e60d5b6236381e8c31858e79ee5
Модуль:Delink
828
264
690
689
2024-08-26T16:45:47Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
-- This module de-links most wikitext.
require("strict")
local yesno = require("Module:Yesno")
local p = {}
local getArgs
local function delinkReversePipeTrick(s)
if s:match("^%[%[|.*[|\n]") then -- Check for newlines or multiple pipes.
return s
end
return s:match("%[%[|(.*)%]%]")
end
local function delinkPipeTrick(s)
-- We need to deal with colons, brackets, and commas, per [[Help:Pipe trick]].
-- First, remove the text before the first colon, if any.
if s:match(":") then
s = s:match("%[%[.-:(.*)|%]%]")
-- If there are no colons, grab all of the text apart from the square brackets and the pipe.
else
s = s:match("%[%[(.*)|%]%]")
end
-- Next up, brackets and commas.
if s:match("%(.-%)$") then -- Brackets trump commas.
s = s:match("(.-) ?%(.-%)$")
elseif s:match(",") then -- If there are no brackets, display only the text before the first comma.
s = s:match("(.-),.*$")
end
return s
end
-- Return wikilink target |wikilinks=target
local function getDelinkedTarget(s)
local result = s
-- Deal with the reverse pipe trick.
if result:match("%[%[|") then
return delinkReversePipeTrick(result)
end
result = mw.uri.decode(result, "PATH") -- decode percent-encoded entities. Leave underscores and plus signs.
result = mw.text.decode(result, true) -- decode HTML entities.
-- Check for bad titles. To do this we need to find the
-- title area of the link, i.e. the part before any pipes.
local target_area
if result:match("|") then -- Find if we're dealing with a piped link.
target_area = result:match("^%[%[(.-)|.*%]%]")
else
target_area = result:match("^%[%[(.-)%]%]")
end
-- Check for bad characters.
if mw.ustring.match(target_area, "[%[%]<>{}%%%c\n]") and mw.ustring.match(target_area, "[%[%]<>{}%%%c\n]") ~= "?" then
return s
end
return target_area
end
local function getDelinkedLabel(s)
local result = s
-- Deal with the reverse pipe trick.
if result:match("%[%[|") then
return delinkReversePipeTrick(result)
end
result = mw.uri.decode(result, "PATH") -- decode percent-encoded entities. Leave underscores and plus signs.
result = mw.text.decode(result, true) -- decode HTML entities.
-- Check for bad titles. To do this we need to find the
-- title area of the link, i.e. the part before any pipes.
local target_area
if result:match("|") then -- Find if we're dealing with a piped link.
target_area = result:match("^%[%[(.-)|.*%]%]")
else
target_area = result:match("^%[%[(.-)%]%]")
end
-- Check for bad characters.
if mw.ustring.match(target_area, "[%[%]<>{}%%%c\n]") and mw.ustring.match(target_area, "[%[%]<>{}%%%c\n]") ~= "?" then
return s
end
-- Check for categories, interwikis, and files.
local colon_prefix = result:match("%[%[(.-):.*%]%]") or "" -- Get the text before the first colon.
local ns = mw.site.namespaces[colon_prefix] -- see if this is a known namespace
if mw.language.isKnownLanguageTag(colon_prefix) or (ns and (ns.canonicalName == "File" or ns.canonicalName == "Category")) then
return ""
end
-- Remove the colon if the link is using the [[Help:Colon trick]].
if result:match("%[%[:") then
result = "[[" .. result:match("%[%[:(.*%]%])")
end
-- Deal with links using the [[Help:Pipe trick]].
if mw.ustring.match(result, "^%[%[[^|]*|%]%]") then
return delinkPipeTrick(result)
end
-- Find the display area of the wikilink
if result:match("|") then -- Find if we're dealing with a piped link.
result = result:match("^%[%[.-|(.+)%]%]")
-- Remove new lines from the display of multiline piped links,
-- where the pipe is before the first new line.
result = result:gsub("\n", "")
else
result = result:match("^%[%[(.-)%]%]")
end
return result
end
local function delinkURL(s)
-- Assume we have already delinked internal wikilinks, and that
-- we have been passed some text between two square brackets [foo].
-- If the text contains a line break it is not formatted as a URL, regardless of other content.
if s:match("\n") then
return s
end
-- Check if the text has a valid URL prefix and at least one valid URL character.
local valid_url_prefixes = {"//", "http://", "https://", "ftp://", "gopher://", "mailto:", "news:", "irc://"}
local url_prefix
for _ ,v in ipairs(valid_url_prefixes) do
if mw.ustring.match(s, '^%[' .. v ..'[^"%s].*%]' ) then
url_prefix = v
break
end
end
-- Get display text
if not url_prefix then
return s
end
s = s:match("^%[" .. url_prefix .. "(.*)%]") -- Grab all of the text after the URL prefix and before the final square bracket.
s = s:match('^.-(["<> ].*)') or "" -- Grab all of the text after the first URL separator character ("<> ).
s = mw.ustring.match(s, "^%s*(%S.*)$") or "" -- If the separating character was a space, trim it off.
local s_decoded = mw.text.decode(s, true)
if mw.ustring.match(s_decoded, "%c") then
return s
end
return s_decoded
end
local function delinkLinkClass(text, pattern, delinkFunction)
if type(text) ~= "string" then
error("Attempt to de-link non-string input.", 2)
end
if type(pattern) ~= "string" or mw.ustring.sub(pattern, 1, 1) ~= "^" then
error('Invalid pattern detected. Patterns must begin with "^".', 2)
end
-- Iterate over the text string, and replace any matched text. using the
-- delink function. We need to iterate character by character rather
-- than just use gsub, otherwise nested links aren't detected properly.
local result = ""
while text ~= "" do
-- Replace text using one iteration of gsub.
text = mw.ustring.gsub(text, pattern, delinkFunction, 1)
-- Append the left-most character to the result string.
result = result .. mw.ustring.sub(text, 1, 1)
text = mw.ustring.sub(text, 2, -1)
end
return result
end
function p._delink(args)
local text = args[1] or ""
if yesno(args.markers) == true then
text = mw.text.killMarkers(text) -- [[Help:Strip markers]]
end
if yesno(args.refs) == true then
-- Remove any [[Help:Strip markers]] representing ref tags. In most situations
-- this is not a good idea - only use it if you know what you are doing!
text = mw.ustring.gsub(text, "UNIQ%w*%-ref%-%d*%-QINU", "")
end
if not (yesno(args.comments) == false) then
text = text:gsub("<!%-%-.-%-%->", "") -- Remove html comments.
end
if not (yesno(args.wikilinks) == false) and args.wikilinks ~= "target" then
-- De-link wikilinks and return the label portion of the wikilink.
text = delinkLinkClass(text, "^%[%[.-%]%]", getDelinkedLabel)
elseif args.wikilinks == "target" then
-- De-link wikilinks and return the target portions of the wikilink.
text = delinkLinkClass(text, "^%[%[.-%]%]", getDelinkedTarget)
end
if not (yesno(args.urls) == false) then
text = delinkLinkClass(text, "^%[.-%]", delinkURL) -- De-link URLs.
end
if not (yesno(args.whitespace) == false) then
-- Replace single new lines with a single space, but leave double new lines
-- and new lines only containing spaces or tabs before a second new line.
text = mw.ustring.gsub(text, "([^\n \t][ \t]*)\n([ \t]*[^\n \t])", "%1 %2")
text = text:gsub("[ \t]+", " ") -- Remove extra tabs and spaces.
end
return text
end
function p.delink(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
return p._delink(getArgs(frame, {wrappers = 'Template:Delink'}))
end
return p
eb6cae0d369f288b0b1600633d9bf7874cefdcbc
Модуль:URL
828
265
692
691
2024-08-26T16:45:48Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
function startsWith( source, substring )
if mw.ustring.len( substring ) > mw.ustring.len( source ) then
return false
end
return mw.ustring.sub( source, 1, mw.ustring.len( substring ) ) == substring
end
p = {}
function formatUrlImpl( source, title, length )
local scheme, host, path
local postfix = ''
local arg1, arg2 = source, title
local isTestPage = mw.title.getCurrentTitle().prefixedText == 'Модуль:URL'
-- Две квадратные скобки подряд — [[вики-ссылка]] вместо [ссылки] — возвращаем вход как есть.
if string.find( arg1, "[[", 1, true ) then
local result = arg1
if not isTestPage then
result = result .. '[[Категория:Википедия:Статьи с вики-ссылкой, переданной в Модуль:URL]]'
if arg2 then
-- Если есть arg2, а мы распарсить ссылку не смогли, и значит заменить title не сможем корректно, это есть ошибка.
result = result .. '[[Категория:Википедия:Статьи с ошибочной работой Модуль:URL]]'
end
end
return result
end
-- Более одной квадратной скобки — скорее всего, задано более одного URL — тоже возвращаем как есть.
if select(2, string.gsub( arg1, "%[", "" )) > 1 then
local result = arg1
if not isTestPage then
result = result .. '[[Категория:Википедия:Статьи со сложным входом в Модуль:URL]]'
if arg2 then
-- Если есть arg2, а мы распарсить ссылку не смогли, и значит заменить title не сможем корректно, это есть ошибка.
result = result .. '[[Категория:Википедия:Статьи с ошибочной работой Модуль:URL]]'
end
end
return result
end
source = mw.text.trim( source, "%[%] " )
local titleDelimeterPosition = mw.ustring.find( source, " ", 1 )
if titleDelimeterPosition then
if not title or title == "" then
title = mw.ustring.sub( source, titleDelimeterPosition + 1 )
local postfixDelimeterPosition = mw.ustring.find( title, "%]", 1 )
if postfixDelimeterPosition then
postfix = mw.ustring.sub( title, postfixDelimeterPosition + 1 )
title = mw.ustring.sub( title, 1, postfixDelimeterPosition - 1 )
end
end
source = mw.ustring.sub( source, 1, titleDelimeterPosition - 1 )
end
local hostStartPosition
local schemeDelimeterPosition = mw.ustring.find( source, "://", 1, true )
if schemeDelimeterPosition then
scheme = mw.ustring.sub( source, 1, schemeDelimeterPosition + 2)
hostStartPosition = schemeDelimeterPosition + 3
elseif mw.ustring.find( source, "^//", 1 ) then
scheme = "//"
hostStartPosition = 3
elseif mw.ustring.find( source, "^mailto:", 1 ) then
scheme = "mailto:"
hostStartPosition = 8
elseif mw.ustring.find( source, "@", 1 ) then
scheme = "mailto:"
source = scheme .. source
hostStartPosition = 8
else
scheme = "http://"
source = scheme .. source
hostStartPosition = 8
end
if title then
local finds = mw.ustring.find( arg1, "[", 1, true )
if titleDelimeterPosition and finds and finds > titleDelimeterPosition + 1 then
-- Если titleDelimeterPosition промазал мимо скобки и нашел пробел раньше неё, к примеру "a [b c]",
-- то свернуть всю нашу хиромантию и выдать первый аргумент без изменений.
if arg2 == nil then
return arg1 .. (isTestPage and '' or '[[Категория:Википедия:Статьи со сложным входом в Модуль:URL]]')
-- Если есть arg2, а мы распарсить ссылку не смогли, и значит заменить title не сможем корректно, это есть ошибка.
-- С другой стороны, если arg2 нет, а arg1 очень сложный, то возможно это нормальный ход вещей,
-- и на вход в модуль дана уже очень сильно оформленная ссылка.
else
return arg1 .. (isTestPage and '' or '[[Категория:Википедия:Статьи с ошибочной работой Модуль:URL]]')
end
end
return '[' .. source .. ' ' .. title .. ']' .. postfix
end
local hostDelimeterPosition = mw.ustring.find( source, "/", hostStartPosition, true )
if hostDelimeterPosition then
host = mw.ustring.sub( source, hostStartPosition, hostDelimeterPosition - 1 )
if hostDelimeterPosition == mw.ustring.len( source ) then
path = nil
else
path = mw.ustring.sub( source, hostDelimeterPosition + 1 )
end
else
host = mw.ustring.sub( source, hostStartPosition )
end
-- post-split format options
if startsWith( host, 'www.' ) then
host = mw.ustring.sub( host, 5 )
end
host = mw.language.new( 'en' ):lc( host )
if path and path ~= '' and path ~= '/' then
local title = host .. '/' .. path
if length and #title > length then
title = host .. '/' .. mw.ustring.sub( path, 1, length - #title - 2 ) .. '…'
end
return '[' .. source .. ' ' .. title .. ']' .. postfix
else
return '[' .. source .. ' ' .. host .. ']' .. postfix
end
end
function p.formatUrl( frame )
local url = frame.args[1] or ''
local title = frame.args[2] or ''
local length = frame.args['length'] and tonumber( frame.args['length'] )
url = mw.text.trim( url )
title = mw.text.trim( title )
if url == '' then
return nil
end
if title == '' then
title = nil
end
return formatUrlImpl( url, title, length )
end
function p.formatUrlSingle( context, options, url )
url = mw.text.trim( url )
if url == '' then
return nil
end
local title = nil
if ( options['text'] and options['text'] ~= '' ) then
title = options['text']
end
local length = options['length'] and tonumber( options['length'] )
return formatUrlImpl( url, title, length )
end
return p
a991f879e135a472238c7f589e8d20d92a856d4d
Шаблон:!-
10
266
694
693
2024-08-26T16:45:48Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
|-<noinclude>
{{doc}}
<!-- Пожалуйста, добавляйте категории и интервики на страницу документации! --></noinclude>
4f45a1a9fb060eda6d4afb6850044503035d52bd
Шаблон:Карточка/имя
10
267
696
695
2024-08-26T16:45:49Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{#if:{{{1|}}}|{{{1}}}|{{сначала имя|{{PAGENAME}}}}}}<noinclude>
{{doc}}
</noinclude>
c2c97d1196f5c50a2ec1aa866cd4004526a32383
Шаблон:Карточка/оригинал имени
10
268
698
697
2024-08-26T16:45:50Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{wikidata|p1559[language!:ru]|{{{1|}}}|before={{{before|}}}|separator=<br>|conjunction=<br>|monolingualLangTemplate={{{monolingualLangTemplate|lang}}}|from={{{from|}}}}}<!--
-->{{#if:{{NAMESPACE}}||{{#if:{{{1|}}}|{{#ifeq:{{#invoke:String|find|{{{1|}}}|span}}|0|[[Категория:Википедия:Статьи с оригиналом имени без шаблона lang-XX]]}}}}}}<noinclude>{{doc}}</noinclude>
a294e3f7f61c5206ca5671b72e21804d7a32fcbc
Шаблон:Wikidata/p569
10
269
700
699
2024-08-26T16:45:50Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{#switch:{{{1|}}}|-=|={{#invoke:Wikidata|formatStatements|property=p569|claim-module=Wikidata/date|claim-function=formatDateOfBirthClaim|nocat={{{nocat|}}}{{NAMESPACE}}|suppressAge={{{suppress age|}}}}}|{{#invoke:Infocards|dateOfBirth|{{{1|}}}|{{{2|}}}|suppressAge={{wikidata|P570|plain=true}}{{{suppress age|}}}|nocat={{{nocat|}}}{{NAMESPACE}}}}}}<noinclude>{{doc}}</noinclude>
9643ab18fcd322831b72e38658b58c6b94a914e2
Шаблон:МестоРождения
10
270
702
701
2024-08-26T16:45:51Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{#if:{{{3|}}}|[[{{{3}}}|{{{1}}}]]|{{#if:{{{1|}}}|[[{{{1}}}]]}}}}{{#if:{{NAMESPACE}}{{{nocat|}}}||{{#if:{{{1|}}}|[[Категория:Персоналии по алфавиту]][[Категория:Родившиеся {{#if:{{{2|}}}|{{{2}}}|в {{#ifeq:{{{1}}}|Ленинград|Санкт-Петербурге|{{Локатив|{{{1}}}}}}}}}]]}}}}</includeonly><noinclude> {{doc}}</noinclude>
e03e5faeefe2ece8cfa949e62031800a70ec9773
Шаблон:Wikidata/p570
10
271
704
703
2024-08-26T16:45:51Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{#switch:{{{1|}}}|-=|={{#invoke:Wikidata|formatStatements|property=p570|claim-module=Wikidata/date|claim-function=formatDateOfDeathClaim|nocat={{{nocat|}}}{{NAMESPACE}}}}|{{#invoke:Infocards|dateOfDeath|{{{2|}}}|{{{1|}}}|nocat={{{nocat|}}}{{NAMESPACE}}}}}}<noinclude>{{doc}}</noinclude>
a51af6d007d156cfeacb13a0a4a7471da7d4ed22
Шаблон:МестоСмерти
10
272
706
705
2024-08-26T16:45:52Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{#if:{{{3|}}}|[[{{{3}}}|{{{1}}}]]|{{#if:{{{1|}}}|[[{{{1}}}]]}}}}{{#if:{{NAMESPACE}}||{{#if:{{{1|}}}|[[Категория:Персоналии по алфавиту]][[Категория:Умершие {{#if:{{{2|}}}|{{{2}}}|в {{#ifeq:{{{1}}}|Ленинград|Санкт-Петербурге|{{Локатив|{{{1}}}}}}}}}]]}}}}</includeonly><noinclude> {{doc}}</noinclude>
c641a956648523b96cdbeaf3fe0e9c6a4644d4ad
Шаблон:Wikidata gender switch
10
273
708
707
2024-08-26T16:45:52Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{#switch: {{wikidata|p21|{{lc:{{delink|{{{1|}}}}}}}|plain=true|from={{{from|}}}}}
| 1 | f | fem | female | feminine | ж | жен | женский | женский пол | транс-женщина | Q6581072 | Q1052281 | Q43445 = {{{2}}}
| m | male | masculine | м | муж | мужской | мужской пол | транс-мужчина | Q6581097 | Q2449503 | Q44148 = {{{3}}}
| #default = {{#if:{{{4|}}}|{{{4}}}|{{{3}}}}}
}}<noinclude>
{{doc}}
</noinclude>
24ccdd5a8702a7028386e9b887d3acf1b5f81c34
Шаблон:Орден Ленина
10
274
710
709
2024-08-26T16:45:53Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{#switch: {{{тип|}}}
| воинская часть = [[Файл:Leninorder.svg|40px|link=Орден Ленина|Орден Ленина {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Воинские части, награждённые орденом Ленина]]}}
| город = [[Файл:Leninorder.svg|40px|link=Орден Ленина|Орден Ленина {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Города, награждённые орденом Ленина]]}}
| регион = [[Файл:Leninorder.svg|40px|link=Орден Ленина|Орден Ленина {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Регионы, награждённые орденом Ленина]]}}
| организация = [[Файл:Leninorder.svg|40px|link=Орден Ленина|Орден Ленина {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Организации, награждённые орденом Ленина]]}}
| СМИ | сми = [[Файл:Leninorder.svg|40px|link=Орден Ленина|Орден Ленина {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:СМИ, награждённые орденом Ленина]]}}
| корабль = [[Файл:Leninorder.svg|40px|link=Орден Ленина|Орден Ленина {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Корабли, награждённые орденом Ленина]]}}
| [[Файл:SU Order of Lenin ribbon.svg|40px|link=Орден Ленина|Орден Ленина {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Кавалеры ордена Ленина]]}}
}}<noinclude>
{{doc}}
[[Категория:Шаблоны:Награды:СССР|Ленина]]
</noinclude>
2abac17c2226c03fa1628e5e5ecd11d7a997a10a
Шаблон:Сначала имя
10
275
712
711
2024-08-26T16:45:54Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{safesubst:<noinclude />#ifexpr: {{safesubst:<noinclude />str find|{{safesubst:<noinclude />До символа|{{{1}}}|(}}|,}} = -1 <!--
-->|{{safesubst:<noinclude />До символа|{{{1}}}|(}}<!--
-->|{{safesubst:<noinclude />trim|{{safesubst:<noinclude />После символа|{{safesubst:<noinclude />До символа|{{{1}}}|(}}|,}}}} {{safesubst:<noinclude />До символа|{{safesubst:<noinclude />До символа|{{{1}}}|(}}|,}}<!--
-->}}<noinclude>
{{doc}}
</noinclude>
c3a2e3e13dba0ae595a7c147ca692be2eb183f38
Шаблон:До символа
10
276
714
713
2024-08-26T16:45:54Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{ {{{|safesubst:}}}#invoke:string2|bs|{{{1|}}}|{{{2|}}}|{{{from|1}}}}}<noinclude>{{doc}}</noinclude>
4cd51dc75d5f365cffac57c9577bd2b2f5c7cc3f
Модуль:Infocards
828
277
716
715
2024-08-26T16:45:55Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
local infocards = {}
local calculateAge = true
local dateCat = require( 'Module:Infocards/dateCat' )
local moduleDates = require( 'Module:Dates' )
--[[
Helper function that populates the argument list given that user may need to use a mix of
named and unnamed parameters. This is relevant because named parameters are not
identical to unnamed parameters due to string trimming, and when dealing with strings
we sometimes want to either preserve or remove that whitespace depending on the application.
]]
function infocards._getParameters( frame_args, arg_list )
local new_args = {}
local index = 1
local value
for i,arg in ipairs( arg_list ) do
value = frame_args[arg]
if value == nil then
value = frame_args[index]
index = index + 1
end
new_args[arg] = value
end
return new_args
end
function infocards.isBlank( someString )
return someString == nil or mw.ustring.match(someString, '^%s*$') ~= nil
end
function infocards.isDate ( frame )
local new_args = infocards._getParameters( frame.args, {'s', 't', 'f'} )
local s = new_args['s'] or ''
local t = new_args['t'] or ''
local f = new_args['f'] or ''
local result = infocards.isDateImpl ( s )
if (result) then
return t
else
return f
end
end
function infocards.isDateImpl ( s )
local converted = infocards.convertToDate ( s )
return converted ~= nil
end
function infocards.dateOfBirth( frame )
local new_args = infocards._getParameters( frame.args, {'dateOfBirth', 'dateOfDeath', 'suppressAge', 'nocat'} )
local dateOfBirth = new_args['dateOfBirth'] or ''
local dateOfDeath = new_args['dateOfDeath'] or ''
local suppressAge = new_args['suppressAge'] or ''
local nocat = new_args['nocat'] or mw.title.getCurrentTitle().nsText
return infocards.dateOfBirthImpl( dateOfBirth, dateOfDeath, suppressAge, nocat )
end
function infocards.dateOfBirthImpl( dateOfBirth, dateOfDeath, suppressAge, nocat )
local appendToCategory = infocards.isBlank( nocat )
if ( infocards.isBlank( dateOfBirth ) ) then
if ( appendToCategory ) then
return dateCat.categoryNoBirthDate
else
return ''
end
end
if ( mw.ustring.match( dateOfBirth, '^%s*неизвестн.%s*$' ) ~= nil
or mw.ustring.match( dateOfBirth, '^%s*%?%s*$' ) ~= nil ) then
if ( appendToCategory ) then
return "''неизвестно''" .. dateCat.categoryUnknownBirthDate
else
return "''неизвестно''"
end
end
local appendAge = not (suppressAge ~= '' or not calculateAge) and infocards.isBlank( dateOfDeath )
local parsedDate = infocards.convertToDate ( dateOfBirth )
if ( parsedDate == nil ) then
--[[ Temporary hack in order to enable export dates to wikidata ]]
local bDateStart = '<span class="no-wikidata" data-wikidata-property-id="P569">'
local bDateEnd = '</span>'
if ( appendToCategory ) then
return bDateStart .. dateOfBirth .. bDateEnd .. dateCat.categoryManualWikification
else
return bDateStart .. dateOfBirth .. bDateEnd
end
end
local result = infocards.formatDateImpl ( parsedDate, 'bday', appendToCategory and 'Родившиеся' or nil )
if ( appendAge ) then
-- TODO: месяцы и дни для (нескольких) новорождённых (см. новейшие [[Категория:Родившиеся в ГГГГ году]])
local age = infocards.age ( parsedDate, os.date("*t") )
if ( age and age < 125) then
result = result .. ' <span class="nowrap">(' .. age .. ' ' .. mw.language.new( 'ru' ):plural( age, 'год', 'года', 'лет') .. ')</span>'
end
if ( appendToCategory ) then
if (not age and parsedDate and parsedDate.year ) then
age = os.date('*t').year - parsedDate.year -- при неточной дате
end
if ( age ) then
if ( age > 115 ) then
result = result .. dateCat.categoryBigCurrentAge
elseif ( age >= 0 ) then
result = result .. dateCat.categoryBiographiesOfLivingPersons
else
result = result .. dateCat.categoryNegativeAge
end
end
end
end
return result
end
function infocards.dateOfDeath( frame )
local new_args = infocards._getParameters( frame.args, {'dateOfBirth', 'dateOfDeath', 'nocat'} )
local dateOfBirth = new_args['dateOfBirth'] or ''
local dateOfDeath = new_args['dateOfDeath'] or ''
local nocat = new_args['nocat'] or mw.title.getCurrentTitle().nsText
return infocards.dateOfDeathImpl( dateOfBirth, dateOfDeath, nocat )
end
function infocards.dateOfDeathImpl( dateOfBirth, dateOfDeath, nocat )
if ( infocards.isBlank( dateOfDeath ) ) then
return ''
end
local appendToCategory = infocards.isBlank( nocat )
if ( mw.ustring.match( dateOfDeath, '^%s*неизвестн.%s*$' ) ~= nil
or mw.ustring.match( dateOfDeath, '^%s*%?%s*$' ) ~= nil ) then
if ( appendToCategory ) then
return "''неизвестно''" .. dateCat.categoryUnknownDeathDate
else
return "''неизвестно''"
end
end
local parsedDateOfBirth = infocards.convertToDate ( dateOfBirth )
local parsedDateOfDeath = infocards.convertToDate ( dateOfDeath )
if ( parsedDateOfDeath == nil ) then
--[[ Temporary hack in order to enable export dates to wikidata ]]
local dDateStart = '<span class="no-wikidata" data-wikidata-property-id="P570">'
local dDateEnd = '</span>'
if ( appendToCategory ) then
return dDateStart .. dateOfDeath .. dDateEnd .. dateCat.categoryManualWikification
else
return dDateStart .. dateOfDeath .. dDateEnd
end
end
local result = infocards.formatDateImpl ( parsedDateOfDeath, 'dday', appendToCategory and 'Умершие' or nil )
if ( calculateAge ) then
local age = infocards.age ( parsedDateOfBirth, parsedDateOfDeath )
if ( age and age > 0 ) then
result = result .. ' <span class="nowrap">(' .. age .. ' ' .. mw.language.new( 'ru' ):plural( age, 'год', 'года', 'лет') .. ')</span>'
end
-- returns category to recently deceased persons
local unixAvailable, unixDateOfDeath = pcall(function()
local r = os.time(parsedDateOfDeath)
if ( r ~= os.time() ) then
return r
end
error()
end)
if (appendToCategory) then
if ( unixAvailable and os.time() - unixDateOfDeath < 31536000 ) then
result = result .. dateCat.categoryRecentlyDeceased
elseif (age and age < 0) then
result = result .. dateCat.categoryNegativeAge
end
end
end
return result
end
function infocards.age( parsedBirthDate, parsedFinishDate )
if ( parsedBirthDate == nil or parsedFinishDate == nil ) then
return nil
end
local bd = parsedBirthDate["day"]
local bm = parsedBirthDate["month"]
local by = parsedBirthDate["year"]
local dd = parsedFinishDate["day"]
local dm = parsedFinishDate["month"]
local dy = parsedFinishDate["year"]
if ( bd and bm and by and dd and dm and dy ) then
if ( dm > bm or ( dm == bm and dd >= bd ) ) then
return dy - by
else
return dy - by - 1
end
else
return nil
end
end
function infocards.formatDateImpl( parsedDate, infocardClass, categoryNamePrefix )
local datePart = '<span class="nowrap">'
--Temporary hack in order to enable export dates to wikidata
if infocardClass == "bday" then
datePart = '<span class="no-wikidata" data-wikidata-property-id="P569">'
elseif infocardClass == "dday" then
datePart = '<span class="no-wikidata" data-wikidata-property-id="P570">'
end
local t1 = { day = parsedDate.osday, month = parsedDate.osmonth, year = parsedDate.osyear }
local t2 = { day = parsedDate.day, month = parsedDate.month, year = parsedDate.year }
datePart = datePart .. moduleDates.formatWikiImpl( t1, t2, infocardClass, categoryNamePrefix )
datePart = datePart .. '</span>'
return datePart
end
function infocards.convertToDate( possibleDateString )
possibleDateString = mw.ustring.gsub( possibleDateString, '−', '-')
local simpleDate = mw.ustring.match(possibleDateString, '^%s*([%-%d%.]+)%s*$', 0)
if ( simpleDate ) then
return infocards.convertToDateNewStylePart( simpleDate )
end
local complexDate1, complexDate2 = mw.ustring.match(possibleDateString, '^%s*([%-%d%.]+)%s*%(([%-%d%.]+)%)%s*$', 0)
if ( complexDate1 and complexDate2) then
local table1 = infocards.convertToDateNewStylePart( complexDate1 )
local table2 = infocards.convertToDateOldStylePart( complexDate2 )
if ( table1 and table2 ) then
return {
year = table1["year"], month = table1["month"], day = table1["day"],
osyear = table2["year"], osmonth = table2["month"], osday = table2["day"]
}
else
return nil
end
end
return nil
end
function infocards.convertToDateNewStylePart( possibleDateString )
local ny = mw.ustring.match(possibleDateString, '^(%-?%d+)$', 0)
if (ny ~= nil) then
return {year = tonumber(ny)}
end
return infocards.convertToDateCommonPart( possibleDateString )
end
function infocards.convertToDateOldStylePart( possibleDateString )
local nd = mw.ustring.match(possibleDateString, '^(%-?%d+)$', 0)
if (nd ~= nil) then
return {day = tonumber(nd)}
end
return infocards.convertToDateCommonPart( possibleDateString )
end
function infocards.convertToDateCommonPart( possibleDateString )
local sDay, sMonth, sYear
local day, month, year
sDay, sMonth, sYear = mw.ustring.match( possibleDateString, '^(%d?%d)%.(%d?%d)%.(%-?%d+)$', 0 )
if sDay ~= nil and sMonth ~= nil and sYear ~= nil then
day = tonumber( sDay )
month = tonumber( sMonth )
year = tonumber( sYear )
if day >= 1 and day <= 32 and month >= 1 and month <= 12 then
return { day = day, month = month, year = year }
end
end
sDay, sMonth = mw.ustring.match( possibleDateString, '^(%d?%d)%.(%d?%d+)$', 0 )
if sDay ~= nil and sMonth ~= nil then
day = tonumber( sDay )
month = tonumber( sMonth )
if day >= 1 and day <= 32 and month >= 1 and month <= 12 then
return { day = day, month = month }
end
end
sMonth, sYear = mw.ustring.match( possibleDateString, '^(%d?%d)%.(%-?%d+)$', 0 )
if sMonth ~= nil and sYear ~= nil then
month = tonumber( sMonth )
year = tonumber( sYear )
if month >= 1 and month <= 12 then
return { month = month, year = year }
end
end
return nil
end
return infocards
6c1e746d6605d4d101f6aa9fd3e4824b60c64ef7
Модуль:Infocards/dateCat
828
278
718
717
2024-08-26T16:45:56Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
local p = {}
p.categoryUnknownBirthDate = '[[Категория:Персоналии, чья дата рождения не установлена]]'
p.categoryUnknownDeathDate = '[[Категория:Персоналии, чья дата смерти не установлена]]'
p.categoryBigCurrentAge = '[[Категория:Персоналии с большим текущим возрастом]]' --бывш. [[Категория:Википедия:Статьи о персоналиях с большим текущим возрастом]]
p.categoryNegativeAge = '[[Категория:Персоналии с отрицательным возрастом]]'
-- p.categoryBigDeathAge = '[[Категория:Википедия:Статьи о персоналиях с большим возрастом во время смерти]]' //deleted -d.bratchuk 05-07-2016
p.categoryBiographiesOfLivingPersons = '[[Категория:Википедия:Биографии современников]]'
p.categoryRecentlyDeceased = '[[Категория:Персоналии, умершие менее года назад]]'
p.categoryManualWikification = '[[Категория:Википедия:Статьи с ручной викификацией дат в карточке]]'
p.categoryNoBirthDate = '[[Категория:Персоналии без указанной даты рождения]]' --бывш. [[Категория:Википедия:Персоны без указанной даты рождения]]
return p
6b27e44bc0a4aaafa42074ca16db92b13e4999d4
Модуль:String2
828
279
720
719
2024-08-26T16:45:56Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
--[[
Кое-какие дополнительные функции для строк
]]
local M = {
bs=function(f)-- первый параметр до начала второго параметра (или до конца, если он не встретился)
--необяз. 3-й параметр - с какого по номеру (с 1) символа начинать поиск.
return mw.ustring.sub(f.args[1], 1, (mw.ustring.find(f.args[1],f.args[2],tonumber(f.args[3] or 1),true) or 0)-1)
end;
as=function(f)-- первый параметр после начала второго параметра
return mw.ustring.sub(f.args[1], (mw.ustring.find(f.args[1],f.args[2],1,true) or 0)+1)
end;
Tr=function(s,f,t,cf,df,sf)-- транслитерация первого параметра путём замены символов из второго параметра символами из третьего.
-- Отдельными параметрами можно передавать флаги c, d и s, как в Perl; диапазоны в замене не работают, только в левой части
-- (т.е. дефис надо передавать первым или последним). Второй результат - число заменённых символов
local r, l, l2 = {}, mw.ustring.len(f), mw.ustring.len(t);
for i = 1, l do
r[mw.ustring.sub(f,i,i)] = i<=l2 and mw.ustring.sub(t,i,i) or df and '' or mw.ustring.sub(t,l2,l2)
end
local n2=0;
local res, n = mw.ustring.gsub(
s,
('[%s%s]%s'):format(
cf and '^' or '',
f:gsub('%','%%'):gsub(']','%]'):gsub('^%^','%^'),
sf and '+' or ''
),
sf and function(cc)
n2 = n2+mw.ustring.len(cc)-1;
return mw.ustring.gsub(cc,'.',r)
end or r
)
return res, n+n2
end;
-- tr = function(f) return (M.Tr(f.args[1],f.args[2],f.args[3],f.args['c'],f.args['d'],f.args['s'])) end;-- транслитерировать
-- trс = function(f) return ({M.Tr(f.args[1],f.args[2],f.args[3],f.args['c'],f.args['d'],f.args['s'])})[2] end;-- посчитать символы
Trg = function(s,t,f,fi)-- Производит замену строк произвольной длины (если с fi, регистр не учитывает).
-- Приоритет - по порядку в таблицах.
for n,p in ipairs(t) do
t[n] = {fi and mw.ustring.upper(p) or p,mw.ustring.len(p)}
end
local r,i,l,N = {},1,mw.ustring.len(s),0
while i<=l do
(function()
for n,p in ipairs(t) do
if ( fi and mw.ustring.upper(mw.ustring.sub(s,i,i+p[2]-1)) or mw.ustring.sub(s,i,i+p[2]-1) ) == p[1] then
table.insert(r,f[n]);
i = i+p[2]; N=N+1;
return
end
end
table.insert(r,mw.ustring.sub(s,i,i));
i=i+1;
return
end)()
end
return table.concat(r),N
end;
trg = function(frame)--Работает с номерными аргументами шаблона,если задан параметр u, иначе со своими.
-- Заменяет в первом аргументе аргументы 2, 4, 6... на аргументы 3, 5, 7...
local tf, t, f, i= frame.args['u'] and frame.getParent() or f, {}, {}, 1;
while tf.args[2*i] do t[tf.args[2*i]]=tf.args[2*i+1] or '' end
return ( M.Trg(tf.args[1],t,f,(frame.args['i'] or '')~='') )
end;
join = function (f) --объединяет нумерованные аргументы вызвавшего шаблона
-- от from или 1 до to или первого отсутствующего
-- через первый параметр invoke. Последний элемент можно присоединять иначе, задав второй параметр.
-- По умолчанию ',' & 'и'
-- Если 3-й параметр invoke — "s", строки из пробелов игнорируются; если "_", игнорируются пустые строки
local t, tf, i = {}, f:getParent(), tonumber(f.args.from) or 1
local k,j,m = tonumber(f.args.to),i,f.args[3]
while k and i<=k or tf.args[i] do
if (
({
['_']=function(s)return s~=''end;
['s']=function(s)return not tostring(s):match("^%s*$")end
})[m] or function() return true end
)(tf.args[i]) then
t[j]=tf.args[i];
j=j+1
end;
i=i+1
end
return mw.text.listToText(t,f.args[1],f.args[2] or f.args[1])
end
}
function M.formatRound(frame) --форматирует число, чтобы оно имело order знаков после запятой
return string.format("%0."..frame.args[2].."f",tonumber(frame.args[1]));
end
-- если строка s содержит число, увеличивает первое такое число на n, иначе возращает пустую строку.
-- если число начинается на 0, то увеличенное число будет содержать по крайне мере столько цифр сколько исходное.
function M.increase(s, n)
local a,b,c = string.match(s, "([^0-9]*)([0-9]+)(.*)")
if b==nil then return s end
local num = tonumber(b) + n
if b:sub(1,1)=='0'
then b = string.format("%0"..b:len().."d", num)
else b=num
end
return a .. b .. c
end
function M.ucfirst(frame )
local s = mw.text.trim( frame.args[1] or "" )
local s1 = ""
-- if it's a list chop off and (store as s1) everything up to the first <li>
local lipos = string.find(s, "<li>" )
if lipos then
s1 = string.sub(s, 1, lipos + 3)
s = string.sub(s, lipos + 4)
end
-- s1 is either "" or the first part of the list markup, so we can continue
-- and prepend s1 to the returned string
local letterpos
if string.find(s, "^%[%[[^|]+|[^%]]+%]%]") then
-- this is a piped wikilink, so we capitalise the text, not the pipe
local _
_, letterpos = string.find(s, "|%A*%a") -- find the first letter after the pipe
else
letterpos = string.find(s, '%a')
end
if letterpos then
local first = string.sub(s, 1, letterpos - 1)
local letter = string.sub(s, letterpos, letterpos)
local rest = string.sub(s, letterpos + 1)
return s1 .. first .. string.upper(letter) .. rest
else
return s1 .. s
end
end
return M
1d51eb45a573b689485dad672c0968c18ec3b342
Модуль:Wikidata/date
828
280
722
721
2024-08-26T16:45:56Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
--settings
local nowLabel = 'наст. время'
local moduleDates = require( "Module:Dates" )
local moduleWikidata = require( "Module:Wikidata" )
local dateCat = require("Module:Infocards/dateCat")
-- FIXME: undeclared global variable, used 3 times
local infoclass
local function deepcopy(orig)
local orig_type = type(orig)
local copy
if orig_type == 'table' then
copy = {}
for orig_key, orig_value in next, orig, nil do
copy[deepcopy(orig_key)] = deepcopy(orig_value)
end
setmetatable(copy, deepcopy(getmetatable(orig)))
else -- number, string, boolean, etc
copy = orig
end
return copy
end
local function ageImpl ( bStructure, bPrecision, dStructure, dPrecision )
if ( not bStructure or not dStructure or bPrecision < 10 or dPrecision < 10 ) then
return nil
end
local shift = 0
if ( bStructure.year < 0 and dStructure.year > 0 ) then
shift = -1
end
if ( bPrecision == 10 or dPrecision == 10 ) then
if ( bStructure.month < dStructure.month ) then
return dStructure.year - bStructure.year + shift
end
if ( bStructure.month == dStructure.month ) then
return nil
end
if ( bStructure.month > dStructure.month ) then
return dStructure.year - bStructure.year - 1 + shift
end
end
if ( bStructure.month < dStructure.month ) then
return dStructure.year - bStructure.year + shift
end
if ( bStructure.month == dStructure.month ) then
if ( bStructure.day <= dStructure.day ) then
return dStructure.year - bStructure.year + shift
else
return dStructure.year - bStructure.year - 1 + shift
end
end
if ( bStructure.month > dStructure.month ) then
return dStructure.year - bStructure.year - 1 + shift
end
return nil
end
-- accepts table of time+precision values
local function ageCurrent ( bTable )
local possibleAge = "NYA" -- it means "Not Yet Assigned", not what you imagined!
for bKey, bValue in pairs(bTable) do
if ( bValue.unknown ) then
return nil
end
local bStructure = bValue.structure
local bPrecision = bValue.precision
local dStructure = os.date( "*t" )
local calculatedAge = ageImpl ( bStructure, bPrecision, dStructure, 11 )
if ( possibleAge == "NYA" ) then
possibleAge = calculatedAge
else
if ( possibleAge ~= calculatedAge ) then
possibleAge = nil
end
end
end
return possibleAge
end
-- accepts tables of time+precision values
local function age ( bTable, dTable )
local possibleAge = "NYA" -- it means "Not Yet Assigned", not what you imagined!
for bKey, bValue in pairs( bTable ) do
if ( bValue.unknown ) then
return nil
end
local bStructure = bValue.structure
local bPrecision = bValue.precision
for dKey, dValue in pairs( dTable ) do
if ( dValue.unknown ) then
return nil
end
local dStructure = dValue.structure
local dPrecision = dValue.precision
if ( bValue.calendar == 'julian' and dValue.calendar == 'gregorian' ) then
-- to calculate age, need to adjust bStructure to gregorian calendar
local shift = math.floor(bStructure.year/100-2) - math.floor(bStructure.year/400)
-- TODO: re-implement this properly
bStructure.day = bStructure.day + shift
end
local calculatedAge = ageImpl ( bStructure, bPrecision, dStructure, dPrecision )
if ( possibleAge == "NYA" ) then
possibleAge = calculatedAge
else
if ( possibleAge ~= calculatedAge ) then
possibleAge = nil
end
end
end
end
return possibleAge
end
local function parseISO8601Date(str)
local pattern = "(%-?%d+)%-(%d+)%-(%d+)T"
local Y, M, D = mw.ustring.match( str, pattern )
return tonumber(Y), tonumber(M), tonumber(D)
end
local function parseISO8601Time(str)
local pattern = "T(%d+):(%d+):(%d+)%Z"
local H, M, S = mw.ustring.match( str, pattern)
return tonumber(H), tonumber(M), tonumber(S)
end
local function parseISO8601Offset(str)
if str:sub(-1)=="Z" then return 0,0 end -- ends with Z, Zulu time
-- matches ±hh:mm, ±hhmm or ±hh; else returns nils
local pattern = "([-+])(%d%d):?(%d?%d?)$"
local sign, oh, om = mw.ustring.match( str, pattern)
sign, oh, om = sign or "+", oh or "00", om or "00"
return tonumber(sign .. oh), tonumber(sign .. om)
end
local function parseISO8601(str)
if 'table' == type(str) then
if str.args and str.args[1] then
str = '' .. str.args[1]
else
return 'unknown argument type: ' .. type( str ) .. ': ' .. table.tostring( str )
end
end
local Y,M,D = parseISO8601Date(str)
local h,m,s = parseISO8601Time(str)
local oh,om = parseISO8601Offset(str)
if not Y or not M or not D or not h or not m or not s or not oh or not om then
return nil
end
return tonumber(os.time({year=Y, month=M, day=D, hour=(h+oh), min=(m+om), sec=s}))
end
local function parseClaim ( claim )
if ( claim.mainsnak.snaktype == "value" ) then
local timeISO8601 = string.gsub( string.gsub( tostring( claim.mainsnak.datavalue.value.time ), '-00%-', '-01-' ), '-00T', '-01T' )
local unixtime = parseISO8601( timeISO8601 )
local structure = os.date("*t", unixtime)
local precision = tonumber( claim.mainsnak.datavalue.value.precision )
local calendarmodel = 'gregorian'
if (mw.ustring.find(claim.mainsnak.datavalue.value.calendarmodel, 'Q1985786', 1, true)) then
calendarmodel = 'julian'
end
local item = { structure=structure, precision=precision, calendar = calendarmodel }
return item
elseif ( claim.mainsnak.snaktype == "novalue" ) then
-- novalue
return { unknown="novalue" }
else
--unknown
return { unknown="unknown" }
end
end
-- returns table of time+precision values for specified property
local function parseProperty ( context, options, propertyId )
if ( not context ) then error( 'context not specified'); end
if ( not options ) then error( 'options not specified'); end
if ( not options.entity ) then error( 'options.entity is missing'); end
if ( not propertyId ) then error( 'propertyId not specified'); end
local claims = context.selectClaims( options, propertyId )
if not claims then
return nil
end
local result = {}
for key, claim in pairs( claims ) do
table.insert ( result, parseClaim( claim ) )
end
return result
end
-- проверка на совпадающие даты с разной моделью календаря
local function checkDupDates( t )
if #t > 1 then
local removed = false
local j = 1
-- проверка на совпадающие даты с разной моделью календаря
while (j <= #t) do
local i = 1
while (i <= #t) do
if i ~= j then
if (os.time(t[j].structure) == os.time(t[i].structure)) then
if ((t[j].calendarmodel == 'gregorian') and
(t[i].calendarmodel == 'julian')) then
removed = true
break
else
table.remove(t, i)
end
else
i = i + 1
end
else
i = i + 1
end
end
if removed then
removed = false
table.remove(t, j)
else
j = j+1
end
end
end
end
-- returns first qualifier of specified propertyId
local function getQualifierWithDataValue( statement, qualifierPropertyId )
if ( statement.qualifiers
and statement.qualifiers[qualifierPropertyId] ) then
local qualifiers = statement.qualifiers[qualifierPropertyId]
for _, qualifier in ipairs( qualifiers ) do
if (qualifier.datavalue) then
return qualifier
end
end
end
return nil
end
local p = {}
local function formatDecade( time, categoryNamePrefix )
local bce = ''
local year
if time.year < 0 then
bce = ' до н. э.'
year = math.floor( math.abs( time.year ) / 10 ) * 10
else
year = math.floor( time.year / 10 ) * 10
end
local unit = '-е'
if isGenitive then
unit = '-х'
end
local value = '' .. year .. unit .. bce
if categoryNamePrefix then
return value .. '[[Category:' .. categoryNamePrefix .. ' в ' .. year .. '-е годы' .. bce .. ']]'
end
return value
end
local function formatCentury( time, categoryNamePrefix, isGenitive )
local moduleRoman = require( 'Module:RomanNumber' )
local bce = ''
local century
if time.year < 0 then
bce = ' до н. э.'
century = math.floor( ( math.abs( time.year ) - 1 ) / 100 ) + 1
else
century = math.floor( ( time.year - 1 ) / 100 ) + 1
end
local unit = 'век'
if isGenitive then
unit = 'века'
end
local infix = ' в '
if century == 2 then
infix = ' во '
end
if moduleRoman then
century = moduleRoman.toRomanNumber( century )
end
local value = '[[' .. century .. ' век' .. bce .. '|' .. century .. ' ' .. unit .. bce .. ']]'
if categoryNamePrefix then
return value .. '[[Category:' .. categoryNamePrefix .. infix .. century .. ' веке' .. bce .. ']]'
end
return value
end
local function formatMillenium( time, categoryNamePrefix, isGenitive )
local bce = ''
local millenium
if time.year < 0 then
bce = ' до н. э.'
millenium = math.floor( ( math.abs( time.year ) - 1 ) / 1000 ) + 1
else
millenium = math.floor( ( time.year - 1 ) / 1000 ) + 1
end
local unit = '-е тысячелетие'
if isGenitive then
unit = '-го тысячелетия'
end
local value = '[[' .. millenium .. '-е тысячелетие' .. bce .. '|' .. millenium .. unit .. bce .. ']]'
if categoryNamePrefix then
local infix = ' в '
if millenium == 2 then
infix = ' во '
end
return value .. '[[Category:' .. categoryNamePrefix .. infix .. millenium .. '-м тысячелетии' .. bce .. ']]'
else
return value
end
end
local function formatDateImpl( value, options, microformatClass, categoryPrefix, leftBracket, rightBracket, nolinks, isGenitive )
if ( not value ) then error( 'value not specified'); end
if ( not options ) then error( 'options not specified'); end
-- The calendar model used for saving the data is always the proleptic Gregorian calendar according to ISO 8601.
local timeISO8601 = string.gsub( string.gsub( tostring( value.time ), '-00%-', '-01-' ), '-00T', '-01T' )
local unixtime = parseISO8601( timeISO8601 )
if not unixtime then
return ''
end
local structure = os.date("*t", unixtime)
local precision = tonumber( value.precision )
if precision <= 6 then
return formatMillenium( structure, categoryPrefix, isGenitive )
end
if precision == 7 then
return formatCentury( structure, categoryPrefix, isGenitive )
end
if precision == 8 then
return formatDecade( structure, categoryPrefix, isGenitive )
end
if precision == 9 then
local tCopy = deepcopy( structure )
tCopy.day = nil
tCopy.month = nil
return moduleDates.formatWikiImpl( tCopy, tCopy, infoclass, categoryPrefix, leftBracket, rightBracket, nolinks )
end
-- year and month only
if precision == 10 then
local tCopy = deepcopy( structure )
tCopy.day = nil
return moduleDates.formatWikiImpl( tCopy, tCopy, infoclass, categoryPrefix, leftBracket, rightBracket, nolinks )
end
local calendarmodel = 'gregorian'
if (mw.ustring.find(value.calendarmodel, 'Q1985786', 1, true)) then
calendarmodel = 'julian'
end
if (calendarmodel == 'gregorian') then
return moduleDates.formatWikiImpl( structure, structure, microformatClass, categoryPrefix, leftBracket, rightBracket, nolinks )
else
return p.formatAsJulian( timeISO8601, infoclass, categoryPrefix, leftBracket, rightBracket, nolinks )
end
end
local function formatApproximateDateClaim( context, options, statement, unknownDateCategory )
if ( not context ) then error( 'context not specified'); end
if ( not options ) then error( 'options not specified'); end
if ( not options.entity ) then error( 'options.entity is missing'); end
if ( not statement ) then error( 'statement not specified'); end
if options.nocat then unknownDateCategory = "" end
local qNotSoonerThan = getQualifierWithDataValue( statement, 'P1319' )
local qNotLaterThan = getQualifierWithDataValue( statement, 'P1326' )
if ( qNotSoonerThan or qNotLaterThan ) then
local results = {}
if ( qNotSoonerThan ) then
local formattedDate = formatDateImpl( qNotSoonerThan.datavalue.value, {}, nil, nil, options.leftBracket, options.rightBracket, options.nolinks, true )
local value = 'не ранее ' .. context.wrapSnak( formattedDate, qNotSoonerThan.hash )
table.insert( results, context.wrapQualifier( value, 'P1319' ) )
end
if ( qNotLaterThan ) then
local formattedDate = formatDateImpl( qNotLaterThan.datavalue.value, {}, nil, nil, options.leftBracket, options.rightBracket, options.nolinks, true )
local value = 'не позднее ' .. context.wrapSnak( formattedDate, qNotLaterThan.hash )
table.insert( results, context.wrapQualifier( value, 'P1326' ) )
end
return mw.text.listToText( results, ' и ' , ' и ' ) .. unknownDateCategory .. context.formatRefs( options, statement )
end
return nil
end
function p.formatDateOfBirthClaim( context, options, statement )
local value = formatApproximateDateClaim( context, options, statement, dateCat.categoryUnknownBirthDate )
if value then
return value
end
options['conjunction'] = ' или '
options['value-module'] = 'Wikidata/date'
options['value-function'] = 'formatBirthDate'
options.i18n.somevalue = '\'\'неизвестно\'\'' .. dateCat.categoryUnknownBirthDate
local circumstances = context.getSourcingCircumstances( statement )
for _, itemId in ipairs( circumstances ) do
if itemId == 'Q5727902' then
options.isGenitive = true
break
end
end
local result = context.formatStatementDefault( context, options, statement )
local bTable = { parseClaim( statement ) }
local dTable = parseProperty ( context, options, 'P570' )
if ( bTable and not dTable ) then
local age = ageCurrent( bTable )
if ( age ) then
if ( options.suppressAge == nil or options.suppressAge == '' ) then
result = result .. ' <span style="white-space:nowrap;">(' .. age .. ' ' .. mw.language.new( 'ru' ):plural( age, 'год', 'года', 'лет') .. ')</span>'
end
if ( not options.nocat ) then
if ( age > 115 ) then
result = result .. dateCat.categoryBigCurrentAge
elseif (age >= 0) then
result = result .. dateCat.categoryBiographiesOfLivingPersons
else
result = result .. dateCat.categoryNegativeAge
end
end
end
end
return result
end
function p.formatDateOfDeathClaim( context, options, statement )
local value = formatApproximateDateClaim( context, options, statement, dateCat.categoryUnknownDeathDate )
if value then
return value
end
options['conjunction'] = ' или '
options['value-module'] = 'Wikidata/date'
options['value-function'] = 'formatDeathDate'
options.i18n.somevalue = '\'\'неизвестно\'\'' .. dateCat.categoryUnknownDeathDate
local circumstances = context.getSourcingCircumstances( statement )
for _, itemId in ipairs( circumstances ) do
if itemId == 'Q5727902' then
options.isGenitive = true
break
end
end
local result = context.formatStatementDefault( context, options, statement )
local bTable = parseProperty ( context, options, 'P569' )
local dTable = { parseClaim( statement ) }
if ( bTable and dTable ) then
local age = age( bTable, dTable )
if ( age ) then
if ( options.suppressAge == nil or options.suppressAge == '' ) then
result = result .. ' <span style="white-space:nowrap;">(' .. age .. ' ' .. mw.language.new( 'ru' ):plural( age, 'год', 'года', 'лет') .. ')</span>'
end
if ( not options.nocat and age < 0) then
result = result .. dateCat.categoryNegativeAge
end
end
-- returns category to recently deceased persons
local unixAvailable, unixDateOfDeath = pcall(function()
local r = os.time(dTable[1].structure)
if ( r ~= os.time() ) then
return r
end
error()
end)
if ( unixAvailable and os.time() - unixDateOfDeath < 31536000 and not options.nocat ) then
result = result .. dateCat.categoryRecentlyDeceased
end
end
return result
end
-- Reentry point for Wikidata Snak formatting
function p.formatBirthDate( context, options, value )
if ( not context ) then error( 'context not specified'); end
if ( not options ) then error( 'options not specified'); end
if ( not value ) then error( 'value not specified'); end
local microformatClass = nil
if options.microformat ~= '-' then
microformatClass = options.microformat or 'bday'
end
if ( options.nocat ) then
return formatDateImpl( value, options, microformatClass, nil, options.leftBracket, options.rightBracket, options.nolinks, options.isGenitive )
else
return formatDateImpl( value, options, microformatClass, 'Родившиеся', options.leftBracket, options.rightBracket, options.nolinks, options.isGenitive )
end
end
-- Reentry point for Wikidata Snak formatting
function p.formatDeathDate( context, options, value )
if ( not context ) then error( 'context not specified'); end
if ( not options ) then error( 'options not specified'); end
if ( not value ) then error( 'value not specified'); end
local microformatClass = nil
if options.microformat ~= '-' then
microformatClass = options.microformat or 'dday'
end
if ( options.nocat and options.nocat ~= '' ) then
return formatDateImpl( value, options, microformatClass, nil, options.leftBracket, options.rightBracket, options.nolinks, options.isGenitive )
else
return formatDateImpl( value, options, microformatClass, 'Умершие', options.leftBracket, options.rightBracket, options.nolinks, options.isGenitive )
end
end
-- Reentry point for Wikidata Snak formatting -- default one
function p.formatDate( context, options, value )
if ( not context ) then error( 'context not specified'); end
if ( not options ) then error( 'options not specified'); end
if ( not value ) then error( 'value not specified'); end
local microformatClass = options.microformat or nil
if ( options.nocat and options.nocat ~= '' ) then
return formatDateImpl( value, options, microformatClass, nil, options.leftBracket, options.rightBracket, options.nolinks, options.isGenitive )
else
local categoryPrefix = options.categoryPrefix or nil
return formatDateImpl( value, options, microformatClass, categoryPrefix, options.leftBracket, options.rightBracket, options.nolinks, options.isGenitive )
end
end
function p.formatDateIntervalProperty( context, options )
if ( not context ) then error( 'context not specified' ); end
if ( not options ) then error( 'options not specified' ); end
if ( not options.entity ) then error( 'options.entity missing' ); end
-- Получение нужных утверждений
local WDS = require( 'Module:WikidataSelectors' )
local fromProperty = options.property
if options.from and options.from ~= '' then
fromProperty = options.from
end
local fromClaims = WDS.load( options.entityId, fromProperty )
local toClaims = WDS.load( options.entityId, options.to )
if fromClaims == nil and toClaims == nil then
return ''
end
local formattedFromClaims = {}
if fromClaims then
for i, claim in ipairs( fromClaims ) do
local formattedStatement = context.formatStatement( options, claim )
if formattedStatement then
formattedStatement = '<span class="wikidata-claim" data-wikidata-property-id="' .. string.upper( options.property ) .. '" data-wikidata-claim-id="' .. claim.id .. '">' .. formattedStatement .. '</span>'
table.insert( formattedFromClaims, formattedStatement )
end
end
end
local formattedToClaims = {}
local toOptions = deepcopy( options )
toOptions.property = options.to
toOptions.novalue = nowLabel
if toClaims then
for i, claim in ipairs( toClaims ) do
local formattedStatement = context.formatStatement( toOptions, claim )
if formattedStatement then
formattedStatement = '<span class="wikidata-claim" data-wikidata-property-id="' .. string.upper( toOptions.property ) .. '" data-wikidata-claim-id="' .. claim.id .. '">' .. formattedStatement .. '</span>'
table.insert( formattedToClaims, formattedStatement )
end
end
end
local out = ''
local fromOut = mw.text.listToText( formattedFromClaims, options.separator, options.conjunction )
local toOut = mw.text.listToText( formattedToClaims, options.separator, options.conjunction )
if fromOut ~= '' or toOut ~= '' then
if fromOut ~= '' then
out = fromOut
else
out = '?'
end
if toOut ~= '' then
out = out .. ' — ' .. toOut
else
local withinClaims = nil
if options.within then
WDS.load( options.entityId, options.within )
end
if withinClaims == nil then
out = 'с ' .. out
else
out = out .. ' — ' .. nowLabel
end
end
end
if out ~= '' then
if options.before then
out = options.before .. out
end
if options.after then
out = out .. options.after
end
end
return out
end
local lowestBoundary = '1582-10-05T00:00:00Z'
local lastBoundary = '1918-01-31T00:00:00Z'
local boundaries = {
-- from (G) till next will be diff(G = J + diff), at current
{ lowestBoundary, 10 },
{ '1700-02-29T00:00:00Z', 11 },
{ '1800-02-29T00:00:00Z', 12 },
{ '1900-02-29T00:00:00Z', 13 },
{ lastBoundary, '' },
}
-- Передаваемое время обязано быть по Юлианскому календарю (старому стилю)
function p.formatAsJulian( julTimeISO8601, infocardClass, categoryNamePrefix, leftBracket, rightBracket, nolinks )
if 'table' == type( julTimeISO8601 ) then
if julTimeISO8601.args and julTimeISO8601.args[1] then
julTimeISO8601 = julTimeISO8601.args[1]
else
return 'unknown argument type: ' .. type( julTime ) .. ': ' .. table.tostring( julTime )
end
end
julTimeISO8601 = mw.text.trim( julTimeISO8601 )
julTimeISO8601 = string.gsub( julTimeISO8601, '^+', '' )
local julTime = parseISO8601( julTimeISO8601 )
local t = os.date( "*t", julTime )
if ( julTime < parseISO8601( lowestBoundary ) ) then
-- only julian
if string.find( julTimeISO8601, '-02-29T', 1, true ) then
t = { year = t.year, month = 2, day = 29 }
end
return moduleDates.formatWikiImpl( t, t, infocardClass, categoryNamePrefix, leftBracket, rightBracket, nolinks )
end
if ( julTimeISO8601 >= lastBoundary ) then
return "''некорректная дата (юлианский календарь не используется после 1918-01-26)''"
end
-- julian and grigorian
for i = 1, #boundaries, 1 do
local b1 = boundaries[i][1]
local b2 = boundaries[i + 1][1]
if ( b1 <= julTimeISO8601 and julTimeISO8601 < b2 ) then
local diff = boundaries[i][2]
if string.sub( julTimeISO8601, 1, 10 ) == string.sub( boundaries[i][1], 1, 10 ) then
t = { year = t.year, month = 2, day = 29 }
diff = diff - 1
end
local gregTime = os.date( "*t", julTime + diff * 24 * 60 * 60 )
return moduleDates.formatWikiImpl( t, gregTime, infocardClass, categoryNamePrefix, leftBracket, rightBracket, nolinks )
end
end
return "''ошибка в модуле Модуль:Wikidata/date''"
end
return p
12c2c34efd103d2938bd65421aa550e8c6f26da0
Модуль:Dates
828
281
724
723
2024-08-26T16:45:57Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
--[[
В это модуле собраны функции, связанные с работой с датами.
]]
local monthg = {'января', 'февраля', 'марта', 'апреля', 'мая', 'июня',
'июля', 'августа', "сентября", "октября", "ноября", "декабря"}
local monthd = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
local function DecodeDate(d)-- Ч, М, Г, СЧ, СМ, СГ, хвост
--дата: "%-?%d+"=год, "%d+%.%d+"=число месяца, "%d+%.%d+%.%-?%d+"=ЧМГ,
-- потом в скобках м.б. переопределено для старого стиля начиная с числа
local nd=d:match("^[%d.-]*");
local od=d:match("^[%d.-]*%s*%(%s*([%d.-]*)%s*%)");
local tail = d:match("^[%d.-]+%s*%(%s*[%d.-]+%s*%)%s*(%S.*)") or d:match("^[%d.-]+%s*([^%s%d].*)");
if nd:match('^%-?%d+$' ) then
return nil, nil, tonumber(nd), nil, nil, od and tonumber(od:match("%-?%d+$")),tail
else
local j,m,y=nd:match("^(%d+)%.(%d+)%.?(%-?%d*)");
if j then
if od then
local oj, om, oy = od:match("^(%d+)%.?(%d*)%.?(%-?%d*)");
return j and tonumber(j),
m and tonumber(m),
y>'' and tonumber(y) or nil,
oj and tonumber(oj),
om>'' and tonumber(om) or nil,
oy>'' and tonumber(oy) or nil,
tail
end
return j and tonumber(j), m and tonumber(m), y>'' and tonumber(y) or nil, nil, nil, nil, tail
else return nil
end
end
end
local function Diffy(d1,m1,y1,d0,m0,y0)--аналог Персона/Дата/Прошло лет
return y1-y0 - ( y1*y0<=0 and 1 or 0 ) - ( (m1<m0 or m1==m0 and d1<d0) and 1 or 0 )
end
local function Year0(y,t)-- аналог Год0
if y>0 then return table.concat{
'[[', tostring(y), ' год|', t and tostring(y)..' '..t or tostring(y), ']]'
} else return table.concat{
'[[', tostring(-y), ' год до н. э.|',
t and tostring(-y)..' '..t or tostring(-y),
' до н. э.]]'
}
end
end
local function FormDate(j,m,y,oj,om,oy,mo)-- ~ Персона/Дата/Logic 4
if j then
if not m then return "''формат неверен''" end
if y then return
string.format(
'<span class="nowrap">%s<span style="display:none">(<span class="%s">%04i-%02i-%02i</span>)</span></span>',
table.concat(
oj and (
om and (
oy and {-- ДД ММММ ГГГГ ([[ДД ММММ]] [[ГГГГ]])
oj,' ',monthg[om],' ',oy,
'</span> <span class="nowrap">([[',
j, ' ', monthg[m],']] ',Year0(y),')'
} or {-- ДД ММММ ([[ДД ММММ]]) [[ГГГГ]]
oj,' ',monthg[om],' ([[',j,' ',monthg[m],']]) ',Year0(y)
}
) or {-- ДД [[ДД ММММ|(ДД) ММММ]] [[ГГГГ]]
oj,' [[',j,' ',monthg[m],'|','(',j,') ',monthg[m],']] ',Year0(y)
}
) or {'[[',j,' ',monthg[m],']] ',Year0(y)}
),--/table.concat
({['Рождения']='bday',['Смерти']='dday'})[mo] or '',
y,m,j
)--/string.format
else return
'<span class="nowrap">' .. table.concat(
oj and (
om and {-- ДД ММММ ([[ДД ММММ]])
oj,' ',monthg[om],' ([[',j,' ',monthg[m],']])</span>'
} or {-- ДД [[ДД ММММ|(ДД) ММММ]]
oj,' [[',j,' ',monthg[m],'|','(',j,') ',monthg[m],']]</span>'
}
) or {'[[',j,' ',monthg[m],']]</span>'}
)
end
else
return y and string.format(
'<span class="nowrap">%s<span style="display:none;">(<span class="bday">%04i</span>)</span></span>',
Year0(y,'год'),y) or "''формат неверен''"
end
end
local function GetDate(D)--dd.mm.-?yyyy или -?yyyy-mm-dd в три переменных d,m,y
local d,m,y = d:match('^%s*(%d%d?)[/.]([01]?%d)[/.](%-?%d+)')
if not d then y,m,d = D:match('^%s*(%-?%d+)[-\\]0*(1?%d)[-\\]0*(%d+)') end
return tonumber(d),tonumber(m),tonumber(y)
end
local function Cmp(a,b)--Сравнивает две даты, результат соответственно -1, 0 или 1
local d1,m1,y1 = GetDate(a)
local d2,m2,y2 = GetDate(b)
return d1 and d2 and (--nil, если формат не опознан
y1==y2 and (
m1==m2 and (
d1==d2 and 0 or d1<d2 and -1 or 1
) or m1<m2 and -1 or 1
) or y1<y2 and -1 or 1
)
end
local function Yyyymmdd(r)--Переводит русскую дату в YYYY,MM,DD
local d, m, y, M = mw.ustring.match(r, "^%s*(%d%d?)%s+([а-яА-Я]+)%s+(%d+)")
if not m then return nil end
m = mw.ustring.lower(m)
--тупо перебор
for i = 1, 12 do
if m == monthg[i] then
M = i
break
end
end
if not M then
return nil
end
return tonumber(y), M, tonumber(d)
end
local p = {}
p = {
ifdate=function(f)-- Для шаблона "Если дата", имитирует старое поведение
-- Аргументы передаются шаблону
return f:getParent().args[ mw.ustring.match(frame.args[1],"^[ %d.%-−%()]*$") and 2 or 3 ]
end;
DecodeDate = DecodeDate;
Diffy = Diffy;
Year0 = Year0;
GetDate = GetDate;
Cmp = Cmp;
Yyyymmdd = Yyyymmdd;
diffy = function(f)-- принимает параметры #invoke в виде двух строк-дат
local d1,m1,y1=DecodeDate(f.args[1]);
local d0,m0,y0=DecodeDate(f.args[2])
return Diffy(d1,m1,y1,d0,m0,y0)
end;
monthg=function(f) return monthg[ f.args[1] or f:getParent().args[1] ] end;--realmonth
persdate=function(f)-- Для шаблона Персона/Дата;{{#invoke:dates|persdate|nocat={{NAMESPACE}}}}
local frame=f:getParent();
local catpref,mo,d,d2={['Рождения']='Родившиеся',['Смерти']='Умершие'}, frame.args[1],frame.args[2],frame.args[3]
local cat, j,m,y,oj,om,oy,tail, j2,m2,y2, age = ''
if d then
j,m,y,oj,om,oy,tail=DecodeDate(d:gsub('−','-'));
if not (j or y) then
return (frame.args.nocat and d or d..'[[Category:Википедия:Статьи с ручной викификацией дат в карточке]]')
end
end;
if d2 then
j2,m2,y2 = DecodeDate(d2:gsub('−','-'));
end;
return table.concat{
FormDate(j,m,y,oj,om,oy,mo),
( (frame.args['nopersoncat'] or '')~='' or (f.args['nocat'] or '')~='' ) and '' or table.concat{
'[[Category:Персоналии по алфавиту]]',
j and string.format('[[Category:%s %i %s]]',catpref[mo],j,monthg[m]) or '',
y and string.format('[[Category:%s в %s]]',catpref[mo],y,Year0(y,'году')) or ''
},--/table.concat внутр.
(function(F)--возраст
if not F then return '' end;
local n=F();
return n and string.format(" (%i %s)%s",
n,
mw.getLanguage('ru'):plural(n,'год','года','лет'),
n>150 and '[[Category:Википедия:Статьи о персоналиях с большим текущим возрастом]]' or ''
) or ''
end)( ({
['Рождения']=function()
local now=os.date('*t');
if (not d2 or d2=='') and j and m and y then
return Diffy(now.day,now.month,now.year,j,m,y)
end
end,
['Смерти']=function()
return j and m and y and j2 and m2 and y2 and Diffy(j,m,y,j2,m2,y2);
end,
})[mo] ),--конец вызова функции возраста
tail or '',
cat
}--/table.concat внеш.
end;
formdate=function(f) -- Формирует дату по 3--6 параметрам #invoke или шаблона
--не использовать с пустыми аргументами
if (f.args[1] or '')~='' and (f.args[2] or '')~='' or (f.args[3] or '')~='' then
return FormDate(f.args[1],f.args[2],f.args[3],f.args[4],f.args[5],f.args[6],f.args['m'])
else
local tf=f:getParent();
return FormDate(tf.args[1],tf.args[2],tf.args[3],tf.args[4],tf.args[5],tf.args[6],tf.args['m'])
end
end;
cmp=function(f)--Сравнивает две даты, результат соответственно -1, 0 или 1
return Cmp(f.args[1],f.args[2])
end;
G2J=function(f)--перевод григорианских дат в юлианские, возврат DD.MM.YYYY
--Не знает про 15 октября 1582 года, не работает до нашей эры и после ???99 года
--Если есть второй аргумент, преобразует только ДО этой даты включительно
--Если есть третий аргумент, результат форматирует под Персона/Дата
local d,m,y=GetDate(f.args[1])
if f.args[2] and Cmp(f.args[1],f.args[2])==1 then
return string.format("%i.%i.%i",d,m,y)
end
local shift=math.floor(y/100)-math.floor(y/400)-2
if d-shift>0 then
return f.args[3] and string.format("%i.%i.%i (%i)",d,m,y,d-shift)
or string.format("%i.%i.%i",d-shift,m,y)
else
if m==1 then
return f.args[3]
and string.format("%i.1.%i (%i.12.%i)",d,y,31+d-shift,y-1)
or string.format("%i.12.%i",31+d-shift,y-1)
elseif m==3 then
return f.args[3] and string.format("%i.3.%i (%i.2)", d,y,
(y%4==0 and 29 or 28)+d-shift-(y%100==0 and y%400~=0 and 1 or 0)
)
or string.format("%i.2.%i",
(y%4==0 and 29 or 28)+d-shift-(y%100==0 and y%400~=0 and 1 or 0)
,y)
else
return f.args[3] and string.format(
"%i.%i.%i (%i.%i)", d,m,y, monthd[m-1]+d-shift,m-1
)
or string.format("%i.%i.%i",monthd[m-1]+d-shift,m-1,y)
end
end
end;
-- Переводит русскую дату в YYYY-MM-DD. Возвращает входное значение, если дата уже в этом формате
yyyymmdd = function(f)
local date, hourmin = f.args[1]
if mw.ustring.match(date, "^%s*%d+\-%d+\-%d+") then
return date
end
hourmin = mw.ustring.match(date, "%s+%d+:%d+$")
local y, m, d = Yyyymmdd(date)
if not y then
return '<span class="error">Ошибка: некорректный формат даты.</span>'
end
return string.format('%4i-%02i-%02i', y, m, d) .. (hourmin or '')
end
}
function table.val_to_str ( v )
if "string" == type( v ) then
v = string.gsub( v, "\n", "\\n" )
if string.match( string.gsub(v,"[^'\"]",""), '^"+$' ) then
return "'" .. v .. "'"
end
return '"' .. string.gsub(v,'"', '\\"' ) .. '"'
else
return "table" == type( v ) and table.tostring( v ) or
tostring( v )
end
end
function table.key_to_str ( k )
if "string" == type( k ) and string.match( k, "^[_%a][_%a%d]*$" ) then
return k
else
return "[" .. table.val_to_str( k ) .. "]"
end
end
function table.tostring( tbl )
local result, done = {}, {}
for k, v in ipairs( tbl ) do
table.insert( result, table.val_to_str( v ) )
done[ k ] = true
end
for k, v in pairs( tbl ) do
if not done[ k ] then
table.insert( result,
table.key_to_str( k ) .. "=" .. table.val_to_str( v ) )
end
end
return "{" .. table.concat( result, "," ) .. "}"
end
local function parseISO8601Date(str)
local pattern = "(%-?%d+)%-(%d+)%-(%d+)T"
local Y, M, D = mw.ustring.match( str, pattern )
return tonumber(Y), tonumber(M), tonumber(D)
end
local function parseISO8601Time(str)
local pattern = "T(%d+):(%d+):(%d+)%Z"
local H, M, S = mw.ustring.match( str, pattern)
return tonumber(H), tonumber(M), tonumber(S)
end
local function parseISO8601Offset(str)
if str:sub(-1)=="Z" then return 0,0 end -- ends with Z, Zulu time
-- matches ±hh:mm, ±hhmm or ±hh; else returns nils
local pattern = "([-+])(%d%d):?(%d?%d?)$"
local sign, oh, om = mw.ustring.match( str, pattern)
sign, oh, om = sign or "+", oh or "00", om or "00"
return tonumber(sign .. oh), tonumber(sign .. om)
end
function p.parseISO8601(str)
if 'table'==type(str) then
if str.args and str.args[1] then
str = '' .. str.args[1]
else
return 'unknown argument type: ' .. type( str ) .. ': ' .. table.tostring( str )
end
end
local Y,M,D = parseISO8601Date(str)
local h,m,s = parseISO8601Time(str)
local oh,om = parseISO8601Offset(str)
return tonumber(os.time({year=Y, month=M, day=D, hour=(h+oh), min=(m+om), sec=s}))
end
local g2uBoundary1 = p.parseISO8601('1582-10-15T00:00:00Z')
local g2uBoundary2 = p.parseISO8601('1700-03-12T00:00:00Z')
local g2uBoundary3 = p.parseISO8601('1800-03-13T00:00:00Z')
local g2uBoundary4 = p.parseISO8601('1900-03-14T00:00:00Z')
local g2uBoundary5 = p.parseISO8601('1918-01-26T00:00:00Z') -- декрет Ленина
-- Передаваемое время обязано быть по Григорианскому календарю (новому стилю)
function p.formatWiki( time, infocardClass, categoryNamePrefix )
if 'table'==type( time ) then
if time.args and time.args[1] then
time = tonumber( time.args[1] )
else
return 'unknown argument type: ' .. type( time ) .. ': ' .. table.tostring( time )
end
end
local t = os.date("*t", time)
if time < g2uBoundary1 then
-- выводим просто юлианский календарь. Задавать тут григорианский некорректно
return p.formatWikiImpl( t, t, infocardClass, categoryNamePrefix )
end
-- Специальные даты
if t.year == 1700 and t.month == 3 and t.day == 11 then
return p.formatWikiImpl( {year=1700, month=2, day=29}, t, infocardClass, categoryNamePrefix)
end
if t.year == 1800 and t.month == 3 and t.day == 12 then
return p.formatWikiImpl( {year=1800, month=2, day=29}, t, infocardClass, categoryNamePrefix )
end
if t.year == 1900 and t.month == 3 and t.day == 13 then
return p.formatWikiImpl( {year=1900, month=2, day=29}, t, infocardClass, categoryNamePrefix )
end
if g2uBoundary1 <= time and time < g2uBoundary2 then
return p.formatWikiImpl( os.date("*t", time - 10 * 24 * 60 * 60), t, infocardClass, categoryNamePrefix )
end
if g2uBoundary2 <= time and time < g2uBoundary3 then
return p.formatWikiImpl( os.date("*t", time - 11 * 24 * 60 * 60), t, infocardClass, categoryNamePrefix )
end
if g2uBoundary3 <= time and time < g2uBoundary4 then
return p.formatWikiImpl( os.date("*t", time - 12 * 24 * 60 * 60), t, infocardClass, categoryNamePrefix )
end
if g2uBoundary4 <= time and time < g2uBoundary5 then
return p.formatWikiImpl( os.date("*t", time - 13 * 24 * 60 * 60), t, infocardClass, categoryNamePrefix )
end
--только Григорианский календарь
return p.formatWikiImpl( t, t, infocardClass, categoryNamePrefix )
end
local function ternary ( cond , T , F )
if cond then return T else return F end
end
local nominativeMonthes = {'январь', 'февраль', 'март', 'апрель', 'май', 'июнь',
'июль', 'август', 'сентябрь', 'октябрь', 'ноябрь', 'декабрь'}
local genitivusMonthes = {'января', 'февраля', 'марта', 'апреля', 'мая', 'июня',
'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря'}
local function nominativeYear( year, nolinks )
if ( year >= 0 ) then
return nolinks and year or '[[' .. year .. ' год|' .. year .. ']]'
else
return nolinks and ( 0 - year ) .. ' до н. э.' or '[[' .. ( 0 - year ) .. ' год до н. э.|' .. ( 0 - year ) .. ' до н. э.]]'
end
end
local function inYear( year )
if ( year >= 0 ) then
return '' .. year .. ' году'
else
return '' .. ( 0 - year) .. ' году до н. э.'
end
end
function p.formatWikiImpl( t1, t2, infocardClass, categoryNamePrefix, leftBracket, rightBracket, nolinks )
local nd = t2.day;
local nm = t2.month;
local ny = t2.year;
local od = ternary ( t1.day ~= t2.day , t1.day, nil );
local om = ternary ( t1.month ~= t2.month , t1.month, nil );
local oy = ternary ( t1.year ~= t2.year , t1.year, nil );
if leftBracket == nil then
leftBracket = '('
end
if rightBracket == nil then
rightBracket = ')'
end
local JulianComment = function(s)
return tostring(mw.html.create("abbr")
:attr("title","по юлианскому календарю")
:wikitext(s)
:done())
end
local template =
(nd ~= nil and "1" or "") .. (nm ~= nil and "2" or "") .. (ny ~= nil and "3" or "") ..
(od ~= nil and "4" or "") .. (om ~= nil and "5" or "") .. (oy ~= nil and "6" or "")
local datePart = '<span class="nowrap">'
if (template == "12") then
datePart = datePart .. string.format( nolinks and "%d %s" or "[[%d %s]]",
nd, genitivusMonthes[nm] )
elseif (template == "23") then
datePart = datePart .. string.format( "%s %s",
nominativeMonthes[nm], nominativeYear( ny, nolinks ) )
elseif (template == "3") then
datePart = datePart .. nominativeYear( ny, nolinks )
elseif (template == "123") then
datePart = datePart .. string.format( nolinks and "%d %s %s" or "[[%d %s]] %s",
nd, genitivusMonthes[nm], nominativeYear( ny, nolinks ) )
elseif (template == "124") then
if nolinks then
datePart = datePart .. JulianComment(string.format( "%d", od )
).. string.format( " " .. leftBracket .. "%d" .. rightBracket .. " %s",
nd, genitivusMonthes[nm] )
else
datePart = datePart .. JulianComment(string.format( "%d", od )
).. string.format( " [[%d %s|" .. leftBracket .. "%d" .. rightBracket .. " %s]]",
nd, genitivusMonthes[nm], nd, genitivusMonthes[nm] )
end
elseif (template == "1234") then
if nolinks then
datePart = datePart .. JulianComment(string.format( "%d", od )
).. string.format( " |" .. leftBracket .. "%d" .. rightBracket .. " %s %s",
nd, genitivusMonthes[nm], nominativeYear( ny, nolinks ) )
else
datePart = datePart .. JulianComment(string.format( "%d", od )
).. string.format( " [[%d %s|" .. leftBracket .. "%d" .. rightBracket .. " %s]] %s",
nd, genitivusMonthes[nm], nd, genitivusMonthes[nm], nominativeYear( ny, nolinks ) )
end
elseif (template == "1245") then
datePart = datePart .. JulianComment(string.format( "%d %s", od, genitivusMonthes[om] )
).. string.format(" " .. leftBracket .. (nolinks and "%d %s" or "[[%d %s]]") .. rightBracket .. "", nd, genitivusMonthes[nm] )
elseif (template == "12345") then
datePart = datePart .. JulianComment(string.format( "%d %s", od, genitivusMonthes[om] )
).. string.format(" " .. leftBracket .. (nolinks and "%d %s" or "[[%d %s]]") .. rightBracket .. " %s", nd, genitivusMonthes[nm], nominativeYear( ny, nolinks ) )
elseif (template == "123456") then
datePart = datePart .. JulianComment(string.format( "%d %s %d", od, genitivusMonthes[om], oy ))
.. '</span> <span class="nowrap">'
.. string.format(" " .. leftBracket .. (nolinks and "%d %s %s" or "[[%d %s]] %s") .. rightBracket , nd, genitivusMonthes[nm], nominativeYear( ny, nolinks ) )
else
datePart = datePart .. 'формат неверен'
end
datePart = datePart .. '</span>'
local infocardTemplate =
(nd ~= nil and "1" or "") .. (nm ~= nil and "2" or "") .. (ny ~= nil and "3" or "")
if infocardClass then
if (infocardTemplate == "123") then
datePart = datePart .. string.format('<span style="display:none">(<span class="%s">%04d-%02d-%02d</span>)</span>', infocardClass , ny , nm , nd )
elseif (infocardTemplate == "23") then
datePart = datePart .. string.format('<span style="display:none">(<span class="%s">%04d-%02d</span>)</span>', infocardClass , ny , nm )
elseif (infocardTemplate == "3") then
datePart = datePart .. string.format('<span style="display:none;">(<span class="%s">%04d</span>)</span>', infocardClass , ny )
end
end
if categoryNamePrefix then
if ( nd ~= nil and nm ~= nil) then
datePart = datePart .. '[[Category:' .. categoryNamePrefix .. ' ' .. nd .. ' ' .. genitivusMonthes[nm] .. ']]'
end
if ( ny ~= nil) then
datePart = datePart .. '[[Category:' .. categoryNamePrefix .. ' в ' .. inYear( ny ) .. ']]'
end
end
return datePart
end
return p
902bb6a9ef5ce12ad4cfa19f3d2c964d7e092df7
Шаблон:Lang-en
10
282
726
725
2024-08-26T16:45:57Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<nowiki />[[английский язык|англ.]] {{lang-en2|{{{1}}}}}<noinclude>
{{doc|Lang/doc}}
</noinclude>
6fcc1d4dc63f133033671bf27e48a6e701e126cb
Шаблон:Lang-en2
10
283
728
727
2024-08-26T16:45:57Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{langi|en|{{{1}}}}}<noinclude>
{{doc|Lang/doc}}
</noinclude>
0471cf4d45a13ece481915d5c3e55db65d6aca04
Модуль:Wikidata/Medals
828
284
730
729
2024-08-26T16:45:59Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
local WDS = require( 'Module:WikidataSelectors' )
local moduleDate = require( 'Module:Wikidata/date' )
local awardsOrder = mw.ext.data.get( "Wikidata/awards order.tab" )
local p = {}
local config = {
--Hide award with key QID if there is a reward with value QID
absorption = {
Q16675272 = 'Q654471',
Q16481808 = 'Q8706404',
Q1948730 = 'Q178473',
Q1980962 = 'Q208167',
Q2032399 = 'Q2046996',
Q102183407 = 'Q103819965',
Q1262166 = 'Q80589',
Q749849 = 'Q1358055',
Q4287121 = 'Q4137462',
}
}
--Get string with dates from qualifiers table
local function datesFromQualifier( context, options, qualifierId )
local dates = {}
local qualifiers = options.qualifiers[ qualifierId ]
if qualifiers then
for _, qualifier in pairs( qualifiers ) do
if qualifier.datavalue then
local dateValue = moduleDate.formatDate( context, options, qualifier.datavalue.value )
if dateValue then
table.insert( dates, dateValue )
end
end
end
end
return table.concat( dates, ', ' )
end
--Property function for [[d:Property:P166]]
function p.formatProperty( context, options )
if ( not context ) then error( 'context not specified' ); end;
if ( not options ) then error( 'options not specified' ); end;
if ( not options.entityId ) then error( 'options.entityId missing' ); end;
local claims;
if options.property then -- TODO: Почему тут может не быть property?
claims = context.selectClaims( options, options.property );
end
if claims == nil then
return '' --TODO error?
end
-- Обход всех заявлений утверждения и с накоплением оформленых
-- предпочтительных заявлений в таблице.
local formattedData = {}
for i, claim in ipairs( claims ) do
if ( claim.mainsnak and
claim.mainsnak and
claim.mainsnak.datavalue and
claim.mainsnak.datavalue.type == 'wikibase-entityid'
) then
local valueId = claim.mainsnak.datavalue.value.id
local formattedStatement = context.formatStatement( options, claim )
-- здесь может вернуться либо оформленный текст заявления, либо строка ошибки, либо nil
if ( formattedStatement and formattedStatement ~= '' ) then
formattedStatement = '<span class="wikidata-claim" data-wikidata-property-id="' .. string.upper( options.property ) .. '" data-wikidata-claim-id="' .. claim.id .. '">' .. formattedStatement .. '</span>'
table.insert( formattedData, {
id = valueId,
html = formattedStatement,
} )
end
end
end
-- Удаление дублей (медаль + звание -> звание)
for i, awardData in ipairs( formattedData ) do
local isAbsorptionFound = false
if config.absorption[ awardData.id ] then
local absorptionAwardId = config.absorption[ awardData.id ]
for _, absorptionAwardData in ipairs( formattedData ) do
if absorptionAwardData.id == absorptionAwardId then
isAbsorptionFound = true
break
end
end
end
if isAbsorptionFound then
table.remove( formattedData, i )
end
end
-- Сортировка медалей по старшинству
local orderedData = {}
local lastValue;
if ( type (awardsOrder) == 'table' ) then
-- Если не отсохла stuctured data
for i, awardFields in ipairs( awardsOrder.data ) do
local awardOrder = awardFields[ 1 ]
if awardOrder == '-' then
-- separator
if lastValue ~= '-' then
table.insert( orderedData, '<br>' )
lastHeight = nil
end
else
for k, awardData in ipairs( formattedData ) do
if awardOrder == awardData.id and not awardData.used then
table.insert( orderedData, awardData.html )
formattedData[ k ].used = true
end
end
end
end
end
for i, awardData in ipairs( formattedData ) do
if not awardData.used then
table.insert( orderedData, awardData.html )
end
end
local lastHeight
for i, awardHtml in ipairs( orderedData ) do
local height = mw.ustring.match( awardHtml, 'x%d+px' )
if height and lastHeight and height ~= lastHeight then
table.insert( orderedData, i, '<br>' )
end
lastHeight = height
end
-- создание текстовой строки со списком оформленых заявлений из таблицы
local out = mw.text.listToText( orderedData, options.separator, options.conjunction )
if out ~= '' then
if options.before then
out = options.before .. out
end
if options.after then
out = out .. options.after
end
end
return out
end
local function getImageFromProperty( entityId, propertyId )
local imageClaims = WDS.load( entityId, propertyId )
if imageClaims and #imageClaims > 0 then
for _, claim in ipairs( imageClaims ) do
if claim.type == 'statement' and claim.mainsnak.snaktype == 'value' then
return claim.mainsnak.datavalue.value
end
end
end
return nil
end
-- Получение изображения (планки или иконки) и его размера
function p.getImageFromEntity( entityId, actualDate )
if type( entityId ) ~= "string" then
entityId = entityId.id
end
local image = nil
local size = 'x17px'
local border = false
-- получение изображения планки из элемента
image = getImageFromProperty( entityId, 'P2425' )
if image then
border = true
end
-- получение иконки из элемента
if not image then
image = getImageFromProperty( entityId, 'P2910' )
if image then
size = '40x40px'
end
end
return image, size, border
end
--Value function for [[d:Property:P166]]
function p.formatValue( context, options, statement )
local entityId = statement.id
if not entityId then
return statement
end
local label = mw.wikibase.getLabel( entityId )
local image, size, border = p.getImageFromEntity( entityId )
local recipientCategory = ''
if not options.nocat and options.nocat ~= '' then
recipientCategory = context.extractCategory( { category = 'P7084[P4224:Q24571879]' }, entityId )
if recipientCategory == '' then
recipientCategory = context.extractCategory( { category = 'P2517' }, entityId )
end
end
local dates = ''
if options.qualifiers then
local startDates = {}
dates = datesFromQualifier( context, options, 'P580' )
if dates ~= '' then
local endDates = datesFromQualifier( context, options, 'P582' )
if endDates and endDates ~= '' then
dates = dates .. ' — ' .. endDates
end
else
dates = datesFromQualifier( context, options, 'P585' )
end
if options.qualifiers.P27 then
mw.log('>>>>>>>>>>>>>')
for _, claim in ipairs( options.qualifiers.P27 ) do
if claim and claim.datavalue and claim.datavalue.value and claim.datavalue.value.id then
local categoryOptions = { category = 'P7084[P27:' .. claim.datavalue.value.id .. ']' }
recipientCategory = recipientCategory .. context.extractCategory( categoryOptions, entityId )
end
end
end
end
-- получение ссылки по идентификатору и вывод планки
if image then
local link = mw.wikibase.getSitelink( entityId )
local out = '[[File:' .. image
if border == true then
out = out .. '|border'
end
out = out .. '|' .. size .. '|link='
-- получение ссылки из родительского элемента
-- для степеней обычно только одна общая статья
if not link then
local partOfClaims = WDS.load( entityId, 'P361' ) -- часть от
if not partOfClaims or #partOfClaims == 0 then
partOfClaims = WDS.load( entityId, 'P279' ) -- подкласс от
end
if partOfClaims and #partOfClaims > 0 then
for _, claim in ipairs( partOfClaims ) do
if claim.type == 'statement' and claim.mainsnak.snaktype == 'value' then
link = mw.wikibase.getSitelink( claim.mainsnak.datavalue.value.id )
if link then
break
end
end
end
end
end
if link then
out = out .. link
else
out = out .. 'd:' .. entityId
end
if label then
out = out .. '|' .. label
end
out = out .. ']]'
out = out .. recipientCategory
return out
end
local out = context.formatValueDefault( context, options, statement )
if out and out ~= '' then
if dates ~= '' then
out = out .. ' (' .. dates .. ')'
end
return '<span style="display:inline-block; text-align:left>' .. out .. recipientCategory .. '</span>'
end
return ''
end
--Table for documentation
function p.renderDoc()
local out = {}
for i, awardFields in ipairs( awardsOrder.data ) do
local awardId = awardFields[ 1 ]
local link = '[[d:' .. awardId .. '|' .. awardId .. ']]'
if i == 351 then
-- limits
table.insert( out, '| … || … || … || … || …' )
elseif i > 351 and i < #awardsOrder.data then
-- do nothing
elseif awardId == '-' then
-- separator
table.insert( out, '|' .. i .. '|| colspan="3" | ----' )
else
local image, size, border = p.getImageFromEntity( awardId )
if image then
image = '[[File:' .. image
if border == true then
image = image .. '|border'
end
image = image .. '|' .. size .. ']]'
else
image = ''
end
local label = mw.wikibase.getLabel( awardId ) or ''
local article = mw.wikibase.getSitelink( awardId )
if article then
if label == '' then
label = article
end
label = '[[' .. article .. '|' .. label .. ']]'
end
local countryStatements = mw.wikibase.getBestStatements( awardId, 'P17' )
local countries = {}
if countryStatements then
for _, statement in ipairs( countryStatements ) do
if statement.mainsnak.datavalue and
statement.mainsnak.datavalue.type == 'wikibase-entityid'
then
local countryId = statement.mainsnak.datavalue.value.id
table.insert( countries, mw.wikibase.getLabel( countryId ) )
end
end
end
table.insert( out, '|' .. i .. '||' .. link .. '||' .. image ..
'||' .. label .. '||' .. table.concat( countries, ', ' ) )
end
end
return '{| class="wikitable"\n' ..
'! # !! Элемент !! Планка !! Название !! Государство\n|-\n' ..
table.concat( out, '\n|-\n' ) ..
'\n|}'
end
return p
4de64e0e2181e8a4487f3e18da893fca9f92660d
Модуль:Wikidata/url
828
285
732
731
2024-08-26T16:46:01Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
local p = {}
local function formatLangRefs( options )
local langRefs = {}
if options.qualifiers and options.qualifiers.P407 then
for _, qualifier in ipairs( options.qualifiers.P407 ) do
if ( qualifier
and qualifier.datavalue
and qualifier.datavalue.type == 'wikibase-entityid' ) then
local qualifierId = qualifier.datavalue.value.id
local wbStatus, langRefCodeClaims = pcall( mw.wikibase.getBestStatements, qualifierId, 'P218' )
if wbStatus and langRefCodeClaims then
for _, claim in ipairs( langRefCodeClaims ) do
if ( claim.mainsnak
and claim.mainsnak.datavalue
and claim.mainsnak.datavalue.type == 'string' ) then
local langRefCode = claim.mainsnak.datavalue.value
table.insert( langRefs, options.frame:expandTemplate{ title = 'ref-' .. langRefCode } )
end
end
end
end
end
end
return table.concat( langRefs, '​' )
end
function p.formatUrlValue( context, options, value )
local moduleUrl = require( 'Module:URL' )
local langRefs = formatLangRefs( options )
if not options.length or options.length == '' then
options.length = math.max( 18, 25 - #langRefs )
end
return moduleUrl.formatUrlSingle( context, options, value ) .. langRefs
end
return p
4a9959f45666b35899729e561a73e0535c16e15e
Модуль:Wikidata/P512
828
286
734
733
2024-08-26T16:46:01Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
local p = {}
--[[
Функция формирует строку с викиразметкой для переданного свойства
Принимает: объект контекста для вызова форматтеров и таблицу настройек
Возвращает: вики-форматированную строку
]]
function p.formatAcademicDegree( context, options )
if ( not context ) then error( 'context not specified' ); end;
if ( not options ) then error( 'options not specified' ); end;
if ( not options.entity ) then error( 'options.entity missing' ); end;
local claims = context.selectClaims( options, options.property );
if (claims == nil) then
return ''
end
local blackList = p.getPreviousDegrees( claims )
local formattedClaims = {}
for i, claim in ipairs(claims) do
if (claim.mainsnak.datavalue and not blackList[claim.mainsnak.datavalue.value['numeric-id']]) then
local formattedStatement = context.formatStatement( options, claim )
if (formattedStatement) then
formattedStatement = '<span class="wikidata-claim"' ..
' data-wikidata-property-id="' ..
string.upper( options.property ) ..
'" data-wikidata-claim-id="' ..
claim.id .. '">' ..
formattedStatement .. '</span>'
if (claim.qualifiers) then
formattedStatement = formattedStatement ..
p.formatQualifier( context, options, claim.qualifiers.P585 )
end
formattedStatement = formattedStatement ..
p.formatCorrespondingCategory( claim )
table.insert( formattedClaims, formattedStatement )
end
end
end
-- создание текстовой строки со списком оформленых заявлений из таблицы
return mw.text.listToText( formattedClaims, options.separator, options.conjunction );
end
--[[
Функция помещает в скобки текст первого квалификатора из переданной таблицы
Принимает: объект контекста для вызова форматтеров, таблицу настроеки
и таблицу квалификаторов
Возвращает: отформатированная строка с квалификатором
]]
function p.formatQualifier( context, options, qualifiers )
if (qualifiers~=nil and qualifiers[1] ~= nil) then
return ' (' .. context.formatSnak( options, qualifiers[1] ) .. ')'
end
return ''
end
--[[
Функция формирует список соответствующих ученых степеней нижней ступени (P155)
Например, для "доктор искусствоведения" это будет "кандидат искусствоведения"
Принимает: объект таблицу сущностей - академических степеней персоны (P512)
Возвращает: объект таблицу идентификаторов степеней нижней ступени
]]
function p.getPreviousDegrees( claims )
-- Пока нет нормальной возможности загружать элементы c кэшем
-- снаружи Module:Wikidata, мы эти соответствия захардкодим (без Q)
local correspondingCandidates = {
[16698078] = 19610224, -- архитектор
[17281188] = 19610186, -- биолог
[17281187] = 19610187, -- ветеринар
[17281186] = 19610193, -- военный
[16698080] = 19610195, -- географ
[16698082] = 19610197, -- гео-мин
[17281180] = 18523814, -- искусствовед
[12101789] = 18523811, -- историк
[16698084] = 19610200, -- культуролог
[17281165] = 19610203, -- медик
[17281161] = 19610206, -- педагог
[12101787] = 4212319, -- политолог
[17281156] = 19610208, -- психолог
[17281153] = 19610210, -- сель-хоз
[17281152] = 19610212, -- социолог
[17281125] = 18071588, -- техник
[17281115] = 19610228, -- фармацевт
[17281097] = 18002832, -- физ-мат
[17281087] = 19603970, -- филолог
[17281084] = 19603972, -- философ
[17281079] = 19610312, -- химик
[17281072] = 17744738, -- экономист
[18745564] = 19610320 -- юрист
}
local previousElements = {}
for i, claim in ipairs(claims) do
if(claim.mainsnak.datavalue) then
local entityId = claim.mainsnak.datavalue.value['numeric-id']
if (entityId) then
if correspondingCandidates[entityId] then
previousElements[correspondingCandidates[entityId]] = true
end
end
end
end
return previousElements
end
--[[
Функция формирует вики-разметку категории, соответствующей ученой степени
Принимает: объект таблицу утверждения
Возвращает: строку оформленного текста либо пустую строку
]]
function p.formatCorrespondingCategory (claim)
if ( not claim ) then return '' end;
if ( not claim.mainsnak ) then return '' end;
if claim.mainsnak.datavalue.value['numeric-id'] == 752297 then return '' end
local label = mw.wikibase.label("Q" .. claim.mainsnak.datavalue.value['numeric-id'])
if not label then label = '' end
local result, changes = string.gsub(label, "доктор ", "Категория:Доктора ")
if (changes == 1) then
return '[[' .. result .. ']]'
end
result, changes = string.gsub(label, "кандидат ", "Категория:Кандидаты ")
if (changes == 1) then
return '[[' .. result .. ']]'
end
return ''
end
return p
dea2568f9f334dcfc745eca69d76f89255ac1b2c
Шаблон:Родственный проект
10
287
736
735
2024-08-26T16:46:02Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<templatestyles src="Шаблон:Родственный_проект/styles.css" />
{| role="presentation" class="metadata plainlinks ts-Родственный_проект noprint ruwikiWikimediaNavigation"
|-
! style="width:10%;" | [[Файл:{{#switch: {{lc:{{{проект|}}}}}
| commons|викисклад = Notification-icon-Commons-logo.svg
| meta|metawiki|m|мета|метавики = Notification-icon-Meta-logo.svg
| wikibooks|wbk|wb|b|викиучебник = Notification-icon-Wikibooks-logo.svg
| wikidata|data|викиданные = Notification-icon-Wikidata-logo.svg
| wikiquote|quote|wqt|q|викицитатник = Notification-icon-Wikiquote.svg
| wikipedia|wp|w|википедия = Notification-icon-Wikipedia-logo.svg
| wikisource|source|ws|s|викитека = Notification-icon-Wikisource-logo.svg
| wiktionary|wkt|wdy|d|wikt|викисловарь = Notification-icon-Wiktionary-logo.svg
| wikinews|news|wnw|n|викиновости = Notification-icon-Wikinews-logo.svg
| wikispecies|species|викивиды = Notification-icon-Wikispecies-logo.svg
| wikiversity|wvy|v|викиверситет = Notification-icon-Wikiversity-logo.svg
| wikivoyage|voyage|voy|викигид = Notification-icon-Wikivoyage-logo.svg
| mediawiki|mw|медиа|медиавики = MediaWiki-2020-small-icon.svg
| outreachwiki|outreach = Wikimedia Outreach.svg
| incubator|инкубатор = Notification-icon-Incubator-logo.svg
| #default = Wikimedia-logo-update-2016.svg
}}|24px|class=noviewer {{#switch: {{lc:{{{проект|}}}}}
| wikipedia|wp|w|википедия = skin-invert-image
}}|alt={{#switch: {{lc:{{{проект|}}}}}
| commons|викисклад = Логотип Викисклада
| meta|metawiki|m|мета|метавики = Логотип Метавики
| wikibooks|wbk|wb|b|викиучебник = Логотип Викиучебника
| wikidata|data|викиданные = Логотип Викиданных
| wikiquote|quote|wqt|q|викицитатник = Логотип Викицитатника
| wikipedia|wp|w|википедия = Логотип Википедии
| wikisource|source|ws|s|викитека = Логотип Викитеки
| wiktionary|wkt|wdy|d|wikt|викисловарь = Логотип Викисловаря
| wikinews|news|wnw|n|викиновости = Логотип Викиновостей
| wikispecies|species|викивиды = Логотип Викивидов
| wikiversity|wvy|v|викиверситет = Логотип Викиверситета
| wikivoyage|voyage|voy|викигид = Логотип Викигида
| mediawiki|mw|медиа|медиавики = Логотип Медиавики
| outreachwiki|outreach = Логотип «Викимедия Популяризация»
| incubator|инкубатор = Логотип Инкубатора
| #default = Логотип Викимедии
}}|link=]]
| {{{текст|}}}
{{#if: {{{внизу|}}} |
{{!-}}
{{!}} colspan="2" class="noplainlist" style="text-weight:bold;" {{!}}
{{{внизу}}} }}
|}<noinclude>{{doc}}</noinclude>
87d436c1491fb07718a7bb1c6ab4849dead4626f
Шаблон:Родственный проект/styles.css
10
288
738
737
2024-08-26T16:46:03Z
DuOfOrl
5
1 версия импортирована
sanitized-css
text/css
.ts-Родственный_проект,
.ts-Родственный_проект.metadata:not(.notheme) {
background: var(--background-color-neutral-subtle, #f8f9fa);
border: 1px solid var(--border-color-base, #a2a9b1);
clear: right;
float: right;
font-size: 90%;
margin: 0 0 1em 1em;
padding: .4em;
max-width: 19em;
width: 19em;
line-height: 1.5;
}
.ts-Родственный_проект th,
.ts-Родственный_проект td {
padding: .2em 0;
vertical-align: middle;
}
.ts-Родственный_проект th + td {
padding-left: .4em;
}
@media (max-width: 719px) {
.ts-Родственный_проект {
width: auto;
margin-left: 0;
margin-right: 0;
}
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
50b08ba20d75d9b717bc6920475793f259cd3af1
Шаблон:Орден Красного Знамени
10
289
740
739
2024-08-26T16:46:03Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{#switch: {{{тип|}}}
| воинская часть = [[Файл:Order of Red Banner.svg|34px|link=Орден Красного Знамени|Орден Красного Знамени {{#if: {{{1|}}} | — {{{1}}} }}]]{{#if: {{NAMESPACE}}{{{nocat|}}} || [[Категория:Воинские части, награждённые орденом Красного Знамени]] }}
| город = [[Файл:Order of Red Banner.svg|34px|link=Орден Красного Знамени|Орден Красного Знамени{{#if: {{{1|}}} | — {{{1}}} }}]]{{#if: {{NAMESPACE}}{{{nocat|}}} || [[Категория:Города, награждённые орденом Красного Знамени]] }}
| регион = [[Файл:Order of Red Banner.svg|34px|link=Орден Красного Знамени|Орден Красного Знамени{{#if: {{{1|}}} | — {{{1}}} }}]]{{#if: {{NAMESPACE}}{{{nocat|}}} || [[Категория:Регионы, награждённые орденом Красного Знамени]] }}
| организация = [[Файл:Order of Red Banner.svg|34px|link=Орден Красного Знамени|Орден Красного Знамени{{#if: {{{1|}}} | — {{{1}}} }}]]{{#if: {{NAMESPACE}}{{{nocat|}}} || [[Категория:Организации, награждённые орденом Красного Знамени]] }}
| СМИ | сми = [[Файл:Order of Red Banner.svg|34px|link=Орден Красного Знамени|Орден Красного Знамени {{#if: {{{1|}}} | — {{{1}}} }}]]{{#if: {{NAMESPACE}}{{{nocat|}}} || [[Категория:СМИ, награждённые орденом Красного Знамени]] }}
| корабль = [[Файл:Order of Red Banner.svg|34px|link=Орден Красного Знамени|Орден Красного Знамени{{#if: {{{1|}}} | — {{{1}}} }}]]{{#if: {{NAMESPACE}}{{{nocat|}}} || [[Категория:Корабли, награждённые орденом Красного Знамени]] }} | [[Файл:SU Order of the Red Banner ribbon.svg|40px|link=Орден Красного Знамени|Орден Красного Знамени {{#if: {{{1|}}} | — {{{1}}} }}]]{{#if: {{NAMESPACE}}{{{nocat|}}} || [[Категория:Кавалеры ордена Красного Знамени]] }}
}}<noinclude>
{{doc}}
</noinclude>
a4b6026ef99495ca5077c93a9192ac2427bbb09e
Шаблон:Ряд
10
290
742
741
2024-08-26T16:46:05Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<templatestyles src="Шаблон:Ряд/styles.css" /><table role="presentation" class="infobox-inherit ts-Ряд {{#switch:{{{выровнять|}}}
| влево = pull-left
| вправо = pull-right
| по ширине = pull-justify
| #default = pull-center}}"><tr>{{
#if:{{{1|}}}|<td>{{{1}}}</td>}}{{
#if:{{{2|}}}|<td>{{{2}}}</td>}}{{
#if:{{{3|}}}|<td>{{{3}}}</td>}}{{
#if:{{{4|}}}|<td>{{{4}}}</td>}}{{
#if:{{{5|}}}|<td>{{{5}}}</td>}}{{
#if:{{{6|}}}|<td>{{{6}}}</td>}}{{
#if:{{{7|}}}|<td>{{{7}}}</td>}}{{
#if:{{{8|}}}|<td>{{{8}}}</td>}}{{
#if:{{{9|}}}|<td>{{{9}}}</td>}}{{
#if:{{{10|}}}|<td>{{{10}}}</td>}}
</tr></table><noinclude>{{doc}}</noinclude>
387ead03289de2d203805d43b37873225d7eaa75
Шаблон:Ряд/styles.css
10
291
744
743
2024-08-26T16:46:06Z
DuOfOrl
5
1 версия импортирована
sanitized-css
text/css
.ts-Ряд {
width: auto;
border-collapse: collapse;
}
.ts-Ряд td {
padding-right: 2px;
padding-left: 2px;
text-align: center;
}
.ts-Ряд td:first-child {
padding-left: 0;
text-align: left;
}
.ts-Ряд td:last-child {
padding-right: 0;
text-align:right;
}
.ts-Ряд.pull-left {
}
.ts-Ряд.pull-center {
margin: 0 auto !important;
}
.ts-Ряд.pull-right {
clear: right;
margin: 0 0 0 auto !important;
}
.ts-Ряд.pull-justify {
width: 100%;
}
body.skin-minerva .ts-Ряд {
display: table;
}
body.skin-minerva .ts-Ряд td {
padding: 2px;
}
body.skin-minerva .ts-Ряд:not(.pull-justify) {
width: auto !important;
}
/* [[Категория:Шаблоны:Подстраницы CSS]] */
2229c228f5137296027e241d85449ea3d3a02656
Шаблон:Вложенные кавычки
10
292
746
745
2024-08-26T16:46:07Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{replace
| {{#invoke:string|replace<!--
-->| {{#invoke:string|replace<!--
-->| {{#invoke:string|replace<!--
-->| {{#invoke:string|replace<!--
-->| {{{1|}}}
| pattern = %[%[(.?[^%]{{!}}]-)«(.[^«»]-)»(.?[^%]{{!}}]-){{!}}
| replace = {{хх}}%1<<%2>>%3{{!}}
| plain = false<!--
-->}}
| pattern = %[%[(.?[^%]{{!}}]-)«(.[^«»]-)»(.?[^%[{{!}}]-)%]%]
| replace = [[%1<<%2>>%3{{!}}%1«%2»%3]]
| plain = false<!--
-->}}
| pattern = «(.[^«»]-)»
| replace = „%1“
| plain = false<!--
-->}}
| pattern = <<(.[^<>]-)>>
| replace = «%1»
| plain = false<!--
-->}}}}<noinclude>{{doc}}</noinclude>
48611a5cc8c8ac357e4b2a083c1845c15462160e
Шаблон:Учёная степень
10
293
748
747
2024-08-26T16:46:08Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{#switch: {{{1|}}}
| кандидат = {{#switch: {{{2|}}}
| архитектуры = [[кандидат архитектуры]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты архитектуры]]}}
| биологических наук = [[кандидат биологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты биологических наук]]}}
| ветеринарных наук = [[кандидат ветеринарных наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты ветеринарных наук]]}}
| военно-морских наук = [[кандидат военно-морских наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты военно-морских наук]]}}
| военных наук = [[кандидат военных наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты военных наук]]}}
| географических наук = [[кандидат географических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты географических наук]]}}
| геолого-минералогических наук = [[кандидат геолого-минералогических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты геолого-минералогических наук]]}}
| искусствоведения = [[кандидат искусствоведения]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты искусствоведения]]}}
| исторических наук = [[кандидат исторических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты исторических наук]]}}
| культурологии = [[кандидат культурологии]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты культурологии]]}}
| медицинских наук = [[кандидат медицинских наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты медицинских наук]]}}
| педагогических наук = [[кандидат педагогических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты педагогических наук]]}}
| политических наук = [[кандидат политических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты политических наук]]}}
| психологических наук = [[кандидат психологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты психологических наук]]}}
| сельскохозяйственных наук = [[кандидат сельскохозяйственных наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты сельскохозяйственных наук]]}}
| социологических наук = [[кандидат социологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты социологических наук]]}}
| технических наук = [[кандидат технических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты технических наук]]}}
| фармацевтических наук = [[кандидат фармацевтических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты фармацевтических наук]]}}
| физико-математических наук = [[кандидат физико-математических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты физико-математических наук]]}}
| филологических наук = [[кандидат филологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты филологических наук]]}}
| философских наук = [[кандидат философских наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты философских наук]]}}
| химических наук = [[кандидат химических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты химических наук]]}}
| экономических наук = [[кандидат экономических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты экономических наук]][[Категория:Учёные по алфавиту]][[Категория:Экономисты по алфавиту]]}}
| юридических наук = [[кандидат юридических наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты юридических наук]]}}
| [[кандидат наук]]{{#if:{{NAMESPACE}}||[[Категория:Кандидаты наук]]}}
}}
| доктор = {{#switch: {{{2|}}}
| архитектуры = [[доктор архитектуры]]{{#if:{{NAMESPACE}}||[[Категория:Доктора архитектуры]]}}
| биологических наук = [[доктор биологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора биологических наук]]}}
| ветеринарных наук = [[доктор ветеринарных наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора ветеринарных наук]]}}
| военно-морских наук = [[доктор военно-морских наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора военно-морских наук]]}}
| военных наук = [[доктор военных наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора военных наук]]}}
| географических наук = [[доктор географических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора географических наук]]}}
| геолого-минералогических наук = [[доктор геолого-минералогических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора геолого-минералогических наук]]}}
| искусствоведения = [[доктор искусствоведения]]{{#if:{{NAMESPACE}}||[[Категория:Доктора искусствоведения]]}}
| исторических наук = [[доктор исторических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора исторических наук]]}}
| культурологии = [[доктор культурологии]]{{#if:{{NAMESPACE}}||[[Категория:Доктора культурологии]]}}
| медицинских наук = [[доктор медицинских наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора медицинских наук]]}}
| педагогических наук = [[доктор педагогических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора педагогических наук]]}}
| политических наук = [[доктор политических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора политических наук]]}}
| психологических наук = [[доктор психологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора психологических наук]]}}
| сельскохозяйственных наук = [[доктор сельскохозяйственных наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора сельскохозяйственных наук]]}}
| социологических наук = [[доктор социологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора социологических наук]]}}
| технических наук = [[доктор технических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора технических наук]]}}
| фармацевтических наук = [[доктор фармацевтических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора фармацевтических наук]]}}
| физико-математических наук = [[доктор физико-математических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора физико-математических наук]]}}
| филологических наук = [[доктор филологических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора филологических наук]]}}
| философских наук = [[доктор философских наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора философских наук]]}}
| химических наук = [[доктор химических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора химических наук]]}}
| экономических наук = [[доктор экономических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора экономических наук]][[Категория:Учёные по алфавиту]][[Категория:Экономисты по алфавиту]]}}
| юридических наук = [[доктор юридических наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора юридических наук]]}}
| [[доктор наук]]{{#if:{{NAMESPACE}}||[[Категория:Доктора наук]]}}
}}
}}</includeonly><noinclude>{{doc}}</noinclude>
21fc4a364f53264639c70cc9807f6963ccb36b53
Шаблон:Орден Октябрьской Революции
10
294
750
749
2024-08-26T16:46:08Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{#switch: {{{тип|}}}
| воинская часть = [[Файл:Order of the October Revolution.svg|45px|link=Орден Октябрьской Революции|Орден Октябрьской Революции {{#if: {{{1|}}}| — {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Воинские части, награждённые орденом Октябрьской Революции]]}}
| город = [[Файл:Order of the October Revolution.svg|45px|link=Орден Октябрьской Революции|Орден Октябрьской Революции {{#if: {{{1|}}}| — {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Города, награждённые орденом Октябрьской Революции]]}}
| регион = [[Файл:Order of the October Revolution.svg|45px|link=Орден Октябрьской Революции|Орден Октябрьской Революции {{#if: {{{1|}}}| — {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Регионы, награждённые орденом Октябрьской Революции]]}}
| организация = [[Файл:Order of the October Revolution.svg|45px|link=Орден Октябрьской Революции|Орден Октябрьской Революции {{#if: {{{1|}}}| — {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Организации, награждённые орденом Октябрьской Революции]]}}
| СМИ | сми = [[Файл:Order of the October Revolution.svg|45px|link=Орден Октябрьской Революции|Орден Октябрьской Революции {{#if: {{{1|}}}|— {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:СМИ, награждённые орденом Октябрьской Революции]]}}
| корабль = [[Файл:Order of the October Revolution.svg|45px|link=Орден Октябрьской Революции|Орден Октябрьской Революции {{#if: {{{1|}}}| — {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Корабли, награждённые орденом Октябрьской Революции]]}}
| [[Файл:SU Order of the October Revolution ribbon.svg|40px|link=Орден Октябрьской Революции|Орден Октябрьской Революции {{#if: {{{1|}}}| — {{{1}}}}}]]{{#if:{{NAMESPACE}}{{{nocat|}}}||[[Категория:Кавалеры ордена Октябрьской Революции]]}}
}}<noinclude>
{{doc}}
</noinclude>
c58fd2bbb6f2eea7bf65e4206a596693f9307c98
Шаблон:Учёное звание
10
295
752
751
2024-08-26T16:46:09Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
<includeonly>{{#switch: {{{1|}}}
<!-- современная Россия -->
| РАН = {{#switch: {{{2|}}}| 1 = [[Члены-корреспонденты РАН|член-корреспондент РАН]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты РАН]]}}| 0 = [[Действительные члены РАН|академик РАН]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены РАН]]}}|<!--пустое значение-->}} <!-- Российская академия наук -->
| РАМН = {{#switch: {{{2|}}}| 1 = [[Члены-корреспонденты РАМН|член-корреспондент РАМН]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты РАМН]]}}| 0 = [[Российская академия медицинских наук|академик РАМН]]{{#if:{{NAMESPACE}}||[[Категория:Академики РАМН]]}}|<!--пустое значение-->}} <!-- Российская академия медицинских наук -->
| РАО = {{#switch: {{{2|}}}| 1 = [[Российская академия образования|член-корреспондент РАО]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты РАО]]}}| 0 = [[Действительные члены (академики) Российской академии образования|академик РАО]]{{#if:{{NAMESPACE}}||[[Категория:Академики РАО]]}}|<!--пустое значение-->}} <!-- Российская академия образования -->
| РАСХН = {{#switch: {{{2|}}}| 1 = [[Российская академия сельскохозяйственных наук|член-корреспондент РАСХН]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты РАСХН]]}}| 0 = [[Российская академия сельскохозяйственных наук|академик РАСХН]]{{#if:{{NAMESPACE}}||[[Категория:Академики РАСХН]]}}|<!--пустое значение-->}} <!-- Российская академия сельскохозяйственных наук -->
| РААСН = {{#switch: {{{2|}}}| 1 = [[Члены-корреспонденты Российской академии архитектуры и строительных наук|член-корреспондент РААСН]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты РААСН]]}}| 0 = [[Академики Российской академии архитектуры и строительных наук|академик РААСН]]{{#if:{{NAMESPACE}}||[[Категория:Академики РААСН]]}}|<!--пустое значение-->}} <!-- Российская академия архитектуры и строительных наук -->
| РАХ = {{#switch: {{{2|}}}| 1 = [[Российская академия художеств|член-корреспондент РАХ]]<br />{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты РАХ]]}}| 0 = [[Список действительных членов РАХ|академик РАХ]] {{#if:{{NAMESPACE}}||[[Категория:Действительные члены РАХ]]}}|<!--пустое значение-->}} <!-- Российская академия художеств -->
<!-- СССР -->
| АН СССР = {{#switch: {{{2|}}}| 1 = [[Члены-корреспонденты РАН за всю историю существования|член-корреспондент АН СССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН СССР]]}}| 0 = [[Академики АН СССР|академик АН СССР]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены АН СССР]]}}|<!--пустое значение-->}} <!-- Академия наук СССР -->
| АМН СССР = {{#switch: {{{2|}}}| 1 = [[Академия медицинских наук СССР|член-корреспондент АМН СССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АМН СССР]]}}| 0 = [[Академия медицинских наук СССР|академик АМН СССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АМН СССР]]}}|<!--пустое значение-->}} <!-- Академия медицинских наук СССР (1944—1992) -->
| АПН СССР = {{#switch: {{{2|}}}| 1 = [[Российская академия образования|член-корреспондент АПН СССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АПН СССР]]}}| 0 = [[Российская академия образования|академик АПН СССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АПН СССР]]}}|<!--пустое значение-->}} <!-- Академия педагогических наук СССР (1966—1992) -->
| ВАСХНИЛ = {{#switch: {{{2|}}}| 1 = [[Список членов-корреспондентов ВАСХНИЛ и РАСХН|член-корреспондент ВАСХНИЛ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты ВАСХНИЛ]]}}| 0 = [[Всесоюзная академия сельскохозяйственных наук имени Ленина|академик ВАСХНИЛ]]{{#if:{{NAMESPACE}}||[[Категория:Академики ВАСХНИЛ]]}}|<!--пустое значение-->}} <!-- ВАСХНИЛ (1929—1992) -->
| АА СССР = {{#switch: {{{2|}}}| 1 = [[Российская академия архитектуры и строительных наук|член-корреспондент АА СССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АА СССР]]}}| 0 = [[Российская академия архитектуры и строительных наук|академик АА СССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики Академии архитектуры СССР]]}}|<!--пустое значение-->}} <!-- Академия архитектуры СССР (1934—1956) и Академия строительства и архитектуры СССР (1956—1964) -->
| АХ СССР = {{#switch: {{{2|}}}| 1 = [[Академия художеств СССР|член-корреспондент АХ СССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Академии художеств СССР]]}}| 0 = [[Академия художеств СССР|академик АХ СССР]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены Академии художеств СССР]]}}|<!--пустое значение-->}} <!-- Академия художеств СССР республики ССР -->
| АН АзССР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Азербайджана|член-корреспондент АН Азербайджанской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Азербайджанской ССР]]}}| 0 = [[Национальная академия наук Азербайджана|академик АН Азербайджанской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Азербайджанской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Азербайджанской ССР -->
| АН АрмССР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Республики Армения|член-корреспондент АН Армянской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Армянской ССР]]}}| 0 = [[Действительные члены НАН Армении за всю историю существования|академик АН Армянской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Армянской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Армянской ССР -->
| АН БССР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Беларуси|член-корреспондент АН БССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Академии наук Белорусской ССР]]}}| 0 = [[Национальная академия наук Беларуси|академик АН БССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики Академии наук Белорусской ССР]]}}|<!--пустое значение-->}} <!-- Белорусская академия наук в 1928-1936 гг.; Академия наук Белорусской ССР в 1936-1991 гг. -->
| АН ГрузССР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Грузии|член-корреспондент АН Грузинской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Грузинской ССР]]}}| 0 = [[Национальная академия наук Грузии|академик АН Грузинской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Грузинской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Грузинской ССР -->
| АН МССР = {{#switch: {{{2|}}}| 1 = [[Академия наук Молдавии|член-корреспондент АН МССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Молдавской ССР]]}}| 0 = [[Академия наук Молдавии|академик АН МССР]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены Академии наук Молдавской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Молдавской ССР -->
| АН КазССР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Казахстана|член-корреспондент АН Казахской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Казахской ССР]]}}| 0 = [[Национальная академия наук Казахстана|академик АН Казахской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Казахской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Казахской ССР -->
| АН КиргССР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Кыргызской Республики|член-корреспондент АН Киргизской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Киргизской ССР]]}}| 0 = [[Национальная академия наук Кыргызской Республики|академик АН Киргизской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Киргизской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Киргизской ССР -->
| АН ЛатССР = {{#switch: {{{2|}}}| 1 = [[Академия наук Латвии|член-корреспондент АН Латвийской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Латвийской ССР]]}}| 0 = [[Академия наук Латвии|академик АН Латвийской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Латвийской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Латвийской ССР -->
| АН ЛитССР = {{#switch: {{{2|}}}| 1 = [[Академия наук Литвы|член-корреспондент АН Литовской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Литовской ССР]]}}| 0 = [[Академия наук Литвы|академик АН Литовской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Литовской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Литовской ССР -->
| АН УзССР = {{#switch: {{{2|}}}| 1 = [[Академия наук Узбекистана|член-корреспондент АН Узбекской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Узбекской ССР]]}}| 0 = [[Академия наук Узбекистана|академик АН Узбекской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Узбекской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Узбекской ССР -->
| АН УССР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Украины|член-корреспондент АН УССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН УССР]]}}| 0 = [[Национальная академия наук Украины|академик АН УССР]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены АН УССР]]}}|<!--пустое значение-->}}<!-- Академия наук Украинской ССР -->
| АН ЭССР = {{#switch: {{{2|}}}| 1 = [[Эстонская академия наук|член-корреспондент АН ЭССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Эстонской ССР]]}}| 0 = [[Эстонская академия наук|академик АН ЭССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Эстонской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Эстонской ССР -->
| АПН РСФСР = {{#switch: {{{2|}}}| 1 = [[Российская академия образования|член-корреспондент АПН РСФСР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АПН РСФСР]]}}| 0 = [[Российская академия образования|действительный член АПН РСФСР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АПН РСФСР]]}}|<!--пустое значение-->}} <!-- Академия педагогических наук РСФСР -->
| АН ТаджССР = {{#switch: {{{2|}}}| 1 = [[Академия наук Республики Таджикистан|член-корреспондент АН Таджикской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Таджикской ССР]]}}| 0 = [[Академия наук Республики Таджикистан|действительный член АН Таджикской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Таджикской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Таджикской ССР -->
| АН ТуркССР = {{#switch: {{{2|}}}| 1 = [[Академия наук Туркмении|член-корреспондент АН Туркменской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Туркменской ССР]]}}| 0 = [[Академия наук Туркмении|действительный член АН Туркменской ССР]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Туркменской ССР]]}}|<!--пустое значение-->}} <!-- Академия наук Туркменской ССР -->
<!-- постсоветские страны -->
| НАНБ | АНБ = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Беларуси|член-корреспондент НАНБ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Национальной академии наук Беларуси]]}}| 0 = [[Национальная академия наук Беларуси|академик НАНБ]]{{#if:{{NAMESPACE}}||[[Категория:Академики Национальной академии наук Беларуси]]}}|<!--пустое значение-->}} <!-- Академия наук Беларуси в 1991—1997 гг (АНБ); Национальная академия наук Беларуси (НАН Беларуси, или НАНБ) с 1997 -->
| АНМ = {{#switch: {{{2|}}}| 1 = [[Академия наук Молдавии|член-корреспондент АНМ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АНМ]]}}| 0 = [[Академия наук Молдавии|академик АНМ]]{{#if:{{NAMESPACE}}||[[Категория:Академики Молдовы]]}}|<!--пустое значение-->}}
| ААНБ = {{#switch: {{{2|}}}| 1 = [[Академия аграрных наук Беларуси|член-корреспондент ААНБ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты ААНБ]]}}| 0 = [[Академия аграрных наук Беларуси|академик ААНБ]]{{#if:{{NAMESPACE}}||[[Категория:Академики ААНБ]]}}|<!--пустое значение-->}} <!-- Академия аграрных наук Беларуси (ААН Беларуси) -->
| НАН РК = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Казахстана|член-корреспондент НАН РК]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты НАН Казахстана]]}}| 0 = [[Национальная академия наук Казахстана|академик НАН РК]]{{#if:{{NAMESPACE}}||[[Категория:Академики НАН Казахстана]]}}|<!--пустое значение-->}} <!-- Академия наук Казахстана -->
| НАН КР = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Кыргызской Республики|член-корреспондент НАН КР]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты НАН Кыргызстана]]}}| 0 = [[Национальная академия наук Кыргызской Республики|академик НАН КР]]{{#if:{{NAMESPACE}}||[[Категория:Академики НАН Кыргызстана]]}}|<!--пустое значение-->}} <!-- Академия наук Кыргызстана-->
| НАН РА = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Республики Армения|член-корреспондент НАН РА]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты НАН Армении]]}}| 0 = [[Действительные члены НАН Армении за всю историю существования|академик НАН РА]]{{#if:{{NAMESPACE}}||[[Категория:Академики НАН Армении]]}}|<!--пустое значение-->}} <!-- Национальная академия наук Армении -->
| НАНА = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Азербайджана|член-корреспондент НАНА]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты НАН Азербайджана]]}}| 0 = [[Национальная академия наук Азербайджана|академик НАНА]]{{#if:{{NAMESPACE}}||[[Категория:Академики НАН Азербайджана]]}}|<!--пустое значение-->}} <!-- Национальная академия наук Азербайджана -->
| НАНУ = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Украины|член-корреспондент НАНУ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты НАН Украины]]}}| 0 = [[Национальная академия наук Украины|академик НАНУ]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены НАН Украины]]}}|<!--пустое значение-->}} <!-- Национальная академия наук Украины -->
| НАМНУ = {{#switch: {{{2|}}}| 1 = [[Национальная академия медицинских наук Украины|член-корреспондент НАМНУ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Национальной академии медицинских наук Украины]]}}| 0 = [[Национальная академия медицинских наук Украины|академик НАМНУ]]{{#if:{{NAMESPACE}}||[[Категория:Академики Национальной академии медицинских наук Украины]]}}|<!--пустое значение-->}} <!-- Национальная академия медицинских наук Украины -->
| СПбАН = {{#switch: {{{2|}}}| 1 = [[Петербургская академия наук|член-корреспондент СПбАН]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Петербургской академии наук]]}}| 0 = [[Петербургская академия наук|академик СПбАН]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены Петербургской академии наук]]}}|<!--пустое значение-->}} <!-- Петербургская академия наук -->
| ПАН = {{#switch: {{{2|}}}| 1 = [[Польская академия наук|член-корреспондент ПАН]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Польской академии наук]]}}| 0 = [[Польская академия наук|действительный член ПАН]]{{#if:{{NAMESPACE}}||[[Категория:Действительные члены Польской академии наук]]}}| 2 = [[Польская академия наук|иностранный член ПАН]]{{#if:{{NAMESPACE}}||[[Категория:Иностранные члены Польской академии наук]]}}| 3 = [[Польская академия наук|сотрудник ПАН]]{{#if:{{NAMESPACE}}||[[Категория:Сотрудники Польской академии наук]]}}|<!--пустое значение-->}} <!-- Польская академия наук -->
| НАПНУ = {{#switch: {{{2|}}}| 1 = [[Национальная академия педагогических наук Украины|член-корреспондент НАПНУ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Национальной академии педагогических наук Украины]]}}| 0 = [[Национальная академия педагогических наук Украины|действительный член НАПНУ]]{{#if:{{NAMESPACE}}||[[Категория:Академики Национальной академии педагогических наук Украины]]}}|<!--пустое значение-->}} <!-- Национальная академия педагогических наук Украины -->
| НАПрНУ = {{#switch: {{{2|}}}| 1 = [[Национальная академия правовых наук Украины|член-корреспондент НАПрНУ]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Национальной академии правовых наук Украины]]}}| 0 = [[Национальная академия правовых наук Украины|действительный член НАПрНУ]]{{#if:{{NAMESPACE}}||[[Категория:Академики Национальной академии правовых наук Украины]]}}|<!--пустое значение-->}} <!-- Национальная академия правовых наук Украины -->
| НАН Грузии = {{#switch: {{{2|}}}| 1 = [[Национальная академия наук Грузии|член-корреспондент НАН Грузии]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты Академии наук Грузии]]}}| 0 = [[Национальная академия наук Грузии|действительный член НАН Грузии]]{{#if:{{NAMESPACE}}||[[Категория:Академики Академии наук Грузии]]}}|<!--пустое значение-->}} <!-- Национальная академия наук Грузии-->
| АН Узбекистана = {{#switch: {{{2|}}}| 1 = [[Академия наук Узбекистана|член-корреспондент АН Узбекистана]]{{#if:{{NAMESPACE}}||[[Категория:Члены-корреспонденты АН Узбекистана]]}}| 0 = [[Академия наук Узбекистана|действительный член АН Узбекистана]]{{#if:{{NAMESPACE}}||[[Категория:Академики АН Узбекистана]]}}|<!--пустое значение-->}} <!-- Академия наук Узбекистана -->
<!-- Научное звание -->
| {{#switch: {{{2|}}}| 1 = [[доцент]]| доцент = [[доцент]]| 0 = [[профессор (звание)|профессор]] | профессор = [[профессор (звание)|профессор]] |<!--пустое значение-->}} <!-- не академики -->
}}</includeonly><noinclude>{{doc}}</noinclude>
c96f56648a68c3a7ea133f232c7bf1196d3fa462
Шаблон:Установлена проверка на неизвестные параметры
10
296
754
753
2024-08-26T16:46:10Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{ombox
|name = Установлена проверка на неизвестные параметры
|text = В этом шаблоне установлена [[Модуль:Check for unknown parameters|проверка на неизвестные параметры]], добавляющая страницы в {{c|{{#if:{{{категория|}}}|{{{категория|}}}|Страницы с неизвестными параметрами шаблона {{ROOTPAGENAME}}}}|В}}.
|type = notice
}}<includeonly>{{no-doc|[[Категория:Шаблоны с установленной проверкой на неизвестные параметры]]{{#ifexist: Категория:{{#if:{{{категория|}}}|{{{категория|}}}|Страницы с неизвестными параметрами шаблона {{ROOTPAGENAME}}}} || [[Категория:Шаблоны с установленной проверкой на неизвестные параметры и несуществующей категорией]] }}|nocat={{{nocat|}}}}}</includeonly><noinclude>{{doc-inline}}
См. [[Модуль:Check for unknown parameters]] и [[:Категория:Википедия:Неизвестные параметры шаблонов]].
Добавляет {{Категория с размером|Шаблоны с установленной проверкой на неизвестные параметры и несуществующей категорией}}.
[[Категория:Шаблоны:Предупреждения]]
[[Категория:Шаблоны:Для документирования шаблонов]]
{{doc-end}}
</noinclude>
cd47e06eec53b65393adba1f3143d6cd3d6cc54c
Шаблон:C
10
297
756
755
2024-08-26T16:46:10Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{#switch: {{{2}}}
| Р = {{{к|к}}}атегории
| Д = {{{к|к}}}атегории
| В = {{{к|к}}}атегорию
| Т = {{{к|к}}}атегорией
| П = {{{к|к}}}атегории
| ю = {{{к|к}}}атегорию
| ей | й = {{{к|к}}}атегорией
| и = {{{к|к}}}атегории
| {{{к|к}}}атегория
}} «[[:Категория:{{{1}}}|{{вложенные кавычки|{{{1}}}}}]]»<noinclude>{{doc}}</noinclude>
29dc241d0737db87ea05ae164b21b3bdc0da3f83
Шаблон:Заготовка шаблона
10
298
758
757
2024-08-26T16:46:12Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{#invoke:TemplateDataDoc|generateBlank|{{#if:{{{1|}}}|{{{1}}}|{{BASEPAGENAME}}}}|description={{{описание|}}}}}<noinclude>{{doc}}</noinclude>
b451404244fd6898bc134564ddcb8941eca7f64a
Модуль:TemplateDataDoc
828
299
760
759
2024-08-26T16:46:12Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
require( 'strict' );
local docSubPage = mw.message.new( 'Templatedata-doc-subpage' ):plain();
local p = {};
local lastNumber = 0;
-- Enable/disable additional spacing for block-formatted templates
local formatBlockSpaces = true;
-- Params that should not be shown in code
local deprecatedParams = {
'nocat',
'from',
'nocoord',
'nocatcoord',
'Автооформление заголовка',
'автооформление заголовка',
'Ширина',
'ширина',
'Ширина изображения',
'ширина изображения',
'Ширина логотипа',
'ширина логотипа',
'Ширина автографа',
'ширина автографа',
};
local noDocNote = 'TemplateDataDoc: Запишите страницу для отображения заполненного шаблона.';
function p.processJson( json )
local status, data = pcall( mw.text.jsonDecode, json );
if status == false then
return nil;
end
if not data[ 'paramOrder' ] then
data[ 'paramOrder' ] = {};
for paramName, paramData in pairs( data[ 'params' ] ) do
table.insert( data[ 'paramOrder' ], paramName );
end
end
for _, param in ipairs( deprecatedParams ) do
if data[ 'params' ][ param ] ~= nil then
data[ 'params' ][ param ][ 'deprecated' ] = '-';
end
end
return data;
end
function p.getTemplateData( pageName )
local title = mw.title.makeTitle( 0, pageName );
if not title or not title.exists then
return false
end
local content = title:getContent()
if not content then
return false;
end;
local json = mw.ustring.match( content, '<[Tt]emplate[Dd]ata%s*>(.*)</[Tt]emplate[Dd]ata%s*>' );
if not json then
return nil;
end
return p.processJson( json )
end
function p.getValue( data, key )
if data[ key ] then
return data[ key ];
end
-- Numbered keys return as numbers
local nkey = tonumber( key );
if nkey ~= nil and data[ nkey ] then
return data[ nkey ];
end
return {};
end
-- See https://phabricator.wikimedia.org/diffusion/ETDA/browse/master/Specification.md?as=remarkup
-- We need a global format value for the 'block' and 'inline': [[phab:T205438]]
function p.convertFormatString( rawTemplateFormat )
local formatType = rawTemplateFormat or 'inline';
local templateFormat = formatType;
local isBlockFormatted = false;
if formatType == 'block' then
templateFormat = '{{_\n| _ = _\n}}';
isBlockFormatted = true;
elseif formatType == 'inline' then
templateFormat = '{{_|_=_}}';
end
return templateFormat, isBlockFormatted, formatType;
end
function p.getFormatParts( rawTemplateFormat, templateName )
local templateFormat, isBlockFormatted, formatType = p.convertFormatString( rawTemplateFormat );
local nameFormat = mw.ustring.match( templateFormat, '^[^|]+' );
local paramKeyFormat = mw.ustring.match( templateFormat, '%|[^=]+=' );
local paramValueFormat = mw.ustring.match( templateFormat, '=[^}]+' );
paramValueFormat = mw.ustring.sub( paramValueFormat, 2 );
local endFormat = mw.ustring.match( templateFormat, '%}%}.*$' );
local startFormat = mw.ustring.gsub( nameFormat, '_', templateName );
return isBlockFormatted, formatType, startFormat, endFormat, paramKeyFormat, paramValueFormat;
end
function p.formatKeyValue( key, parameterData, formatData )
if parameterData[ 'deprecated' ] then
return '';
end
local args = formatData.args;
local parameterName = key;
local nkey = tonumber( key );
-- Add additional spacing to string keys
if formatBlockSpaces and formatData.parameterLength and formatData.formatType ~= 'inline' and ( nkey == nil or lastNumber ~= nkey - 1 ) then
while mw.ustring.len( key ) < formatData.parameterLength do
key = key .. ' ';
end
end
-- Remove numbering for adjacent numbered keys
if nkey ~= nil and lastNumber == nkey - 1 then
key = '';
lastNumber = nkey;
end
local value = '';
if formatData.valueKey == 'example' and parameterData[ 'example' ] then
-- Example
value = parameterData[ 'example' ];
else
if formatData.valueKey == 'description' and parameterData[ 'description' ] then
-- Description
value = parameterData[ 'description' ];
if value ~= '' then
value = '<!-- ' .. value .. ' -->';
end
elseif parameterData[ 'autovalue' ] then
-- Autovalue
value = parameterData[ 'autovalue' ];
end
if args[ '$' .. parameterName ] and args[ '$' .. parameterName ] ~= '' then
-- Custom values from template call
value = args[ '$' .. parameterName ];
end
end
local formattedKey = mw.ustring.gsub( formatData.paramKeyFormat, '_+', key, 1 );
if key == '' then
formattedKey = mw.ustring.gsub( formattedKey, '=', '' );
end
return formattedKey .. mw.ustring.gsub( formatData.paramValueFormat, '_', value, 1 );
end
function p.generateBlankCode( templateData, templateName, args )
if templateData == false then
return '{{' .. templateName .. '}}';
end
local parameterLength = 0;
for i, parameterName in ipairs( templateData[ 'paramOrder' ] ) do
local parameterData = p.getValue( templateData[ 'params' ], parameterName );
if not parameterData[ 'deprecated' ] then
local length = mw.ustring.len( parameterName );
if length > parameterLength then
parameterLength = length;
end
end
end
local isBlockFormatted, formatType, startFormat, endFormat, paramKeyFormat, paramValueFormat = p.getFormatParts( templateData[ 'format' ], templateName );
local out = startFormat;
lastNumber = 0;
for i, parameterName in ipairs( templateData[ 'paramOrder' ] ) do
local parameterData = p.getValue( templateData[ 'params' ], parameterName );
if parameterData[ 'inherits' ] then
parameterData = p.getValue( templateData[ 'params' ], parameterData[ 'inherits' ] );
end
out = out .. p.formatKeyValue( parameterName, parameterData, {
args = args,
valueKey = ( args[ 'description' ] and 'description' or nil ),
formatType = formatType,
isBlockFormatted = isBlockFormatted,
parameterLength = parameterLength,
paramKeyFormat = paramKeyFormat,
paramValueFormat = paramValueFormat,
} );
end
return out .. endFormat;
end
function p.generateBlank( frame )
local frame = mw.getCurrentFrame();
local getArgs = require( 'Module:Arguments' ).getArgs;
local args = getArgs( frame );
local templateName = frame.args[ 1 ];
table.remove( args, 1 );
local docPage = 'Template:' .. templateName .. '/' .. docSubPage;
local templateData = p.getTemplateData( docPage );
local out = p.generateBlankCode( templateData, templateName, args );
local previewNote = ''
if templateData == false and frame:preprocess('{{REVISIONID}}') == '' then
previewNote = '<div class="warningbox">' .. noDocNote .. '</div>';
end
return previewNote .. frame:extensionTag{ name = 'pre', content = out };
end
function p.generateExampleCode( templateData, templateName, args )
if templateData == false then
return '{{' .. templateName .. '}}';
end
local parameterLength = 0;
for i, parameterName in ipairs( templateData[ 'paramOrder' ] ) do
local parameterData = p.getValue( templateData[ 'params' ], parameterName );
if parameterData[ 'example' ] and not parameterData[ 'deprecated' ] then
local length = mw.ustring.len( parameterName );
if length > parameterLength then
parameterLength = length;
end
end
end
local isBlockFormatted, formatType, startFormat, endFormat, paramKeyFormat, paramValueFormat = p.getFormatParts( templateData[ 'format' ], templateName );
local out = startFormat;
lastNumber = 0;
for i, parameterName in ipairs( templateData[ 'paramOrder' ] ) do
local parameterData = p.getValue( templateData[ 'params' ], parameterName );
if parameterData[ 'inherits' ] then
parameterData = p.getValue( templateData[ 'params' ], parameterData[ 'inherits' ] );
end
if parameterData[ 'example' ] then
out = out .. p.formatKeyValue( parameterName, parameterData, {
args = args,
valueKey = 'example',
formatType = formatType,
isBlockFormatted = isBlockFormatted,
parameterLength = parameterLength,
paramKeyFormat = paramKeyFormat,
paramValueFormat = paramValueFormat,
} );
end
end
return out .. endFormat;
end
function p.generateExample( frame )
local frame = mw.getCurrentFrame();
local args = frame.args;
local templateName = frame.args[ 1 ];
local docPage = 'Template:' .. templateName .. '/' .. docSubPage;
local templateData = p.getTemplateData( docPage );
local out = p.generateExampleCode( templateData, templateName, args );
local previewNote = ''
if templateData == false and frame:preprocess('{{REVISIONID}}') == '' then
previewNote = '<div class="warningbox">' .. noDocNote .. '</div>';
end
return previewNote .. frame:preprocess( out ) .. frame:extensionTag{ name = 'pre', content = out };
end
return p;
53670b81abac0bc22d720fbe984944dcd709da7c
Шаблон:Пример шаблона
10
300
762
761
2024-08-26T16:46:13Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{#invoke:TemplateDataDoc|generateExample|{{#if:{{{1|}}}|{{{1}}}|{{BASEPAGENAME}}}}}}<noinclude>{{doc}}</noinclude>
4675b6574c5d274f0525e41569d31a0a4881168f
Шаблон:Uses Wikidata
10
301
764
763
2024-08-26T16:46:14Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{Родственный проект
| проект = викиданные
| текст = Этот {{module other|модуль|шаблон}} использует {{#if: {{{раздел|{{{section|}}}}}}
| Свойства [[Викиданные|Викиданных]]; детальней см. [[#{{{раздел|{{{section|}}}}}}|§ {{{раздел|{{{section}}}}}}]].
| [[ВП:Викиданные{{!}}свойств{{#if:{{{2|}}}|а|о}} Викиданных]]:
}}
| внизу = {{#if: {{{раздел|{{{section|}}}}}} || <div class="plainlist"><ul>{{#invoke:Uses Wikidata|usesProperty}}</ul></div> }}
}}<noinclude>
{{doc}}
</noinclude>
5d62bf72bc1eea3b38bb5a9cd82eecf54b02fe45
Шаблон:Старый-новый стиль,примечание
10
302
766
765
2024-08-26T16:46:14Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
В случае, если дата рождения/смерти в источниках приведена по [[Юлианский календарь|старому стилю]], рекомендуется указывать её по новому стилю, а после указать в скобках отличающуюся часть даты по старому стилю. Например,
* «13.05.1801 (1)» будет отображено как [[13 мая|1 (13) мая]] [[1801 год|1801]];
* «12.06.1801 (31.05)» будет отображено как 31 мая ([[12 июня]]) [[1801 год|1801]];
* «12.01.1802 (31.12.1801)» будет отображено как 31 декабря 1801 ([[12 января]] [[1802 год|1802]]).
При этом в статью будут автоматически подставлены категории даты рождения/смерти по ''новому'' стилю. Учтите, что разница между датами нового и старого стиля составляет 13 дней в XX и XXI веках, 12 дней в XIX веке, 11 дней в XVIII веке, 10 дней в XVII и XVI веках (начиная с 5 (15) октября 1582 года).<noinclude>{{doc-inline}}Шаблон предназначен для подстановки в качестве примечания к полям «дата рождения», «дата смерти» для страниц документации шаблонов-карточек типа «Персона».
Параметров не принимает.
Вызов: {{tl|Старый-новый стиль,примечание}} {{doc-end}} [[Категория:Википедия:Шаблоны, встраиваемые в шаблоны-карточки:Личности]]
</noinclude>
7f8754eb5c2401671df545a1cd8b315f66f86463
Модуль:Uses Wikidata
828
303
768
767
2024-08-26T16:46:15Z
DuOfOrl
5
1 версия импортирована
Scribunto
text/plain
local p = {}
local function incat( name, label, dot )
local incat = ''
if not dot then dot = '' end
local pincat = mw.site.stats.pagesInCategory( name, all )
if pincat ~= 0 then incat = "[[:К:" .. name .. "|" .. label .. tostring( pincat ) .. "]]" .. dot end
return incat
end
local function trackingcats(p_num)
local result =
incat("ВП:" .. p_num .. ":використовується", "'''U:'''", "•") ..
incat("ВП:" .. p_num .. ":відсутня", "'''<s>U:'''", "</s>•") ..
incat("Вікідані:" .. p_num .. ":відсутня", "'''<s>D:'''", "</s>•") ..
incat("Вікідані:" .. p_num .. ":відрізняється", "'''↑↓:'''")
if result ~= "" then return "[<span></span>" .. result .. "]"
else return "" end
end
function p.usesProperty(frame)
local parent = frame.getParent(frame)
local result = ''
local ii = 1
while true do
local p_num = ""
if parent.args[ii] or frame.args[ii] then
p_num = mw.text.trim(string.upper(parent.args[ii] or frame.args[ii])) end
if p_num ~= "" then
local label = mw.wikibase.label(p_num) or "БЕЗ НАЗВИ"
result = result .. "<li><b><i>[[d:Property:" .. p_num .. "|<small>" ..
p_num .. "</small>:" .. label .. "]]</i></b> {[[d:Property talk:" ..
p_num .. "|обс]]•[[d:Special:WhatLinksHere/Property:" ..
p_num .. "|исп]]}" ..
trackingcats(p_num) .. "</li>"
ii = ii + 1
else break
end
end
return result
end
return p
8a066acc434e0611d04134bb82a5fdd9d4fb5f9f
Шаблон:Политик/doc
10
304
770
769
2024-08-26T16:46:16Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
{{docpage}}
{{OnLua|CategoryForProfession}}
{{Установлена проверка на неизвестные параметры}}
{{Uses Wikidata|p18|p19|p20|p22|p25|p27|p40|p102|p106|p109|p140|p166|p512|p569|p570|p856|p1142|p1559}}
Этот [[Википедия:Шаблоны-карточки|шаблон-карточка]] предназначен для статей о политиках. Для государственных деятелей существует шаблон {{t|Государственный деятель}}.
Внимание, шаблон поддерживает загрузку дат смерти и рождения через [[ВП:Викиданные|Викиданные]]. Не заполняйте в шаблоне эти поля, если есть возможность использовать wikidata.
''Отметим, что большинство полей автоматически загружают информации из [[ВП:Викиданные|Викиданных]].''
Категории профессий по алфавиту и по странам добавляются автоматически на основе информации из викиданных. В случае если персоналию не следует добавлять в категорию, то существует параметр <code>без категорий=</code> в которым следует перечислить названия исключаемых категорий через точку с запятой. Пример использования — [[Special:Diff/70059213/70085957]].
Если есть только год рождения/смерти, так и пишите только цифры года.
{{Старый-новый стиль,примечание}}
== Заготовка для копирования ==
{{Заготовка шаблона}}
== Пример использования ==
{{Пример шаблона}}
== Отслеживающие категории ==
В служебных целях используется ряд скрытых отслеживающих категорий:
{{categorytree|Отслеживающие категории:Шаблон:Политик|категории|0|title=}}
== TemplateData ==
<templatedata>
{
"params": {
"nocat": {
"type": "boolean"
},
"from": {
"type": "line"
},
"имя": {
"aliases": [
"Имя"
],
"label": "имя",
"description": "имя персоны",
"type": "line",
"example": "Джон Доу"
},
"оригинал имени": {
"aliases": [
"Оригинал имени"
],
"label": "оригинал имени",
"description": "имя персоны на языке оригинала, обёрнутое в шаблон серии {{t|lang-en}}",
"example": "{{lang-en|John Doe}}",
"type": "string"
},
"изображение": {
"aliases": [
"Изображение"
],
"label": "изображение",
"description": "изображение персоны (P18)",
"example": "example.jpg",
"type": "wiki-file-name"
},
"ширина": {
"aliases": [
"Ширина"
],
"label": "ширина",
"type": "number",
"description": "размер изображения"
},
"описание изображения": {
"aliases": [
"Описание изображения"
],
"label": "описание изображения",
"description": "должно характеризовать портрет",
"type": "string"
},
"имя при рождении": {
"aliases": [
"Имя при рождении"
],
"label": "имя при рождении",
"description": "имя при рождении, если было изменено",
"type": "string"
},
"псевдонимы": {
"aliases": [
"Псевдонимы"
],
"label": "псевдонимы",
"type": "string"
},
"дата рождения": {
"aliases": [
"Дата рождения"
],
"label": "дата рождения",
"type": "date",
"description": "дд.мм.гггг (P569)",
"example": "02.01.1960"
},
"дата смерти": {
"aliases": [
"Дата смерти"
],
"label": "дата смерти",
"type": "date",
"description": "дд.мм.гггг (P570)",
"example": "02.01.2000"
},
"место рождения": {
"aliases": [
"Место рождения"
],
"label": "место рождения",
"description": "место рождения (P19)",
"type": "string",
"example": "{{МестоРождения|Лондон}}",
"autovalue": "{{МестоРождения|}}"
},
"место смерти": {
"aliases": [
"Место смерти"
],
"label": "место смерти",
"description": "место смерти (P20)",
"type": "string",
"example": "{{МестоСмерти|Москва}}",
"autovalue": "{{МестоСмерти|}}"
},
"гражданство": {
"aliases": [
"Гражданство",
"страна",
"подданство"
],
"label": "гражданство",
"description": "гражданство (P27)",
"type": "string",
"example": "[[Великобритания]], [[Россия]]"
},
"род деятельности": {
"aliases": [
"Род деятельности"
],
"label": "род деятельности",
"description": "род деятельности (P106)",
"type": "string",
"example": "[[политик]], [[журналист]], [[издатель]]"
},
"образование": {
"aliases": [
"Образование",
"альма-матер"
],
"label": "образование",
"description": "оконченное высшее учебное заведение (P69)",
"type": "string",
"example": "[[Московский государственный университет]]"
},
"учёная степень": {
"aliases": [
"Учёная степень"
],
"label": "учёная степень",
"type": "string",
"description": "учёная степень (P512)",
"example": "{{Учёная степень|доктор|экономических наук}}",
"autovalue": "{{Учёная степень||}}"
},
"вероисповедание": {
"aliases": [
"Вероисповедание"
],
"label": "вероисповедание",
"type": "string",
"description": "вероисповедание персоны",
"example": "[[католицизм]]"
},
"партия": {
"aliases": [
"Партия"
],
"label": "партия",
"type": "string",
"description": "партии и организации",
"example": "[[КПСС]], [[Партия любителей пива]]"
},
"основные идеи": {
"aliases": [
"Основные идеи"
],
"label": "основные идеи",
"type": "string",
"description": "политические взгляды и основные идеи (P1142)",
"example": "[[коммунизм]], [[национализм]]"
},
"отец": {
"aliases": [
"Отец"
],
"label": "отец",
"description": "отец (P22)",
"type": "string"
},
"мать": {
"aliases": [
"Мать"
],
"label": "мать",
"description": "мать (P25)",
"type": "string"
},
"супруг": {
"aliases": [
"Супруг"
],
"label": "супруг",
"description": "супруг (P26)",
"type": "string"
},
"супруга": {
"aliases": [
"Супруга"
],
"label": "супруга",
"description": "супруга (P26)",
"type": "string"
},
"дети": {
"aliases": [
"Дети"
],
"label": "дети",
"description": "дети (P40)",
"type": "string"
},
"награды": {
"aliases": [
"Награды",
"награды и премии"
],
"label": "награды",
"description": "ордена, медали и тому подобное; для них есть специальные шаблоны (P166)",
"type": "string",
"example": "{{ряд | {{Орден Ленина}} | {{Орден Октябрьской Революции}} | {{Орден Красного Знамени}} }}"
},
"автограф": {
"aliases": [
"Автограф"
],
"label": "автограф",
"type": "wiki-file-name",
"description": "отсканированная подпись персоны (P109)"
},
"ширина автографа": {
"aliases": [
"Ширина автографа"
],
"label": "ширина автографа",
"type": "number"
},
"сайт": {
"aliases": [
"Сайт"
],
"label": "сайт",
"type": "url",
"description": "официальный сайт (P856)",
"example": "example.com"
},
"викисклад": {
"aliases": [
"Викисклад"
],
"label": "викисклад",
"description": "название категории на Викискладе (P373)",
"deprecated": true,
"type": "line"
},
"учёное звание": {
"aliases": [
"Учёное звание"
],
"label": "учёное звание",
"type": "string",
"description": "учёное звание",
"example": "{{Учёное звание||0}}",
"autovalue": "{{Учёное звание||}}"
}
},
"description": "Шаблон-карточка для статей о политиках.",
"paramOrder": [
"имя",
"оригинал имени",
"изображение",
"ширина",
"описание изображения",
"имя при рождении",
"псевдонимы",
"дата рождения",
"место рождения",
"дата смерти",
"место смерти",
"гражданство",
"род деятельности",
"образование",
"учёная степень",
"учёное звание",
"вероисповедание",
"партия",
"основные идеи",
"отец",
"мать",
"супруг",
"супруга",
"дети",
"награды",
"автограф",
"ширина автографа",
"сайт",
"викисклад",
"nocat",
"from"
],
"format": "block"
}
</templatedata>
<includeonly>
[[Категория:Шаблоны-карточки:Личности]]
[[Категория:Шаблоны-карточки:Политика]]
</includeonly>
20627691b0800f1de81471e82cb15ed1027bfbd3
Шаблон:Categorytree
10
305
772
771
2024-08-26T16:46:16Z
DuOfOrl
5
1 версия импортирована
wikitext
text/x-wiki
#REDIRECT [[Шаблон:Дерево категорий]]
dbb44c74e7e2d0a61716eb7c903a7ecef6d38d15
Шаблон:Политик
10
259
773
680
2024-08-26T16:49:08Z
DuOfOrl
5
wikitext
text/x-wiki
{{Карточка
|имя = Политик
|from = {{{from|}}}
|стиль_вверху = background:#eaecf0;
|стиль_меток = min-width:9em;
|стиль_внизу = background:#eaecf0;
|вверху = {{карточка/имя|{{{Имя|{{{имя|}}}}}}|from={{{from|}}}}}
|вверху2 = {{{Оригинал имени|}}}
|изображение = {{Карточка/изображение|{{{Изображение|{{{изображение|}}}}}}|size={{{Ширина|}}}|caption={{{Описание изображения|{{{описание изображения|}}}}}}}}
|метка1 = Имя при рождении
|текст1 = {{{Имя при рождении|}}}
|метка2 = Псевдонимы
|текст2 = {{{Псевдонимы|}}}
|метка3 = Дата рождения
|текст3 = {{Персона/Дата|Рождения|{{{Дата рождения|{{{дата рождения|}}}}}}|{{{Дата смерти|{{{дата смерти|}}}}}}}}
|метка4 = Место рождения
|текст4 = {{{Место рождения|{{{место рождения|}}}}}}
|метка5 = Дата смерти
|текст5 = {{Персона/Дата|Смерти|{{{Дата смерти|{{{дата смерти|}}}}}}|{{{Дата рождения|{{{дата рождения|}}}}}}}}
|метка6 = Место смерти
|текст6 = {{{Место смерти|{{{место смерти|}}}}}}
|метка7 = Гражданство
|текст7 = {{{Гражданство|{{{гражданство|}}}}}}
|метка8 = Род деятельности
|текст8 = {{{Род деятельности|{{{род деятельности|}}}}}}
|метка9 = Образование
|текст9 = {{{Образование|}}}
|метка10 = Учёная степень
|текст10 = {{{Учёная степень|}}}
|метка11 = Учёное звание
|текст11 = {{{Учёное звание|}}}
|метка12 = Вероисповедание
|текст12 = {{{Вероисповедание|}}}
|метка13 = Партия
|текст13 = {{{Партия|}}}
|метка14 = Основные идеи
|текст14 = {{{Основные идеи|}}}
|метка15 = Отец
|текст15 = {{{Отец|}}}
|метка16 = Мать
|текст16 = {{{Мать|}}}
|метка17 = Супруг(а)
|текст17 = {{#if: {{{Супруга|}}} | {{{Супруга|}}} | {{{Супруг|}}} }}
|метка18 = Дети
|текст18 = {{{Дети|}}}
|метка19 = Награды
|текст19 = {{{Награды|}}}
|метка20 = Автограф
|текст20 = {{#if:{{{Автограф|}}}|[[Файл:{{{Автограф|}}}|{{#if:{{{Ширина автографа|}}}|{{{Ширина автографа}}}|143px}}]]}}
|внизу = {{{Сайт|}}}
|внизу2 =
}}{{#if:{{NAMESPACE}}{{{nocat|}}}||<!--
-->[[Категория:Персоналии по алфавиту]]<!--
-->[[Категория:Политики по алфавиту]]<!--
-->}}<noinclude>{{doc}}</noinclude>
81154b03594f472ec9e6b56503eb402ed4fc040e
Шаблон:Персона/Дата
10
306
774
2024-08-26T16:50:52Z
DuOfOrl
5
Новая страница: «<includeonly>{{#switch:{{{1}}} |Рождения={{#if:{{{2|}}}|{{#invoke:Infocards|dateOfBirth|{{{2|}}}|{{{3|}}}|nocat={{{nopersoncat|}}}{{NAMESPACE}}}}}} |Смерти={{#invoke:Infocards|dateOfDeath|{{{3|}}}|{{{2|}}}|nocat={{{nopersoncat|}}}{{NAMESPACE}}}} }}</includeonly><noinclude>{{doc}}</noinclude>»
wikitext
text/x-wiki
<includeonly>{{#switch:{{{1}}}
|Рождения={{#if:{{{2|}}}|{{#invoke:Infocards|dateOfBirth|{{{2|}}}|{{{3|}}}|nocat={{{nopersoncat|}}}{{NAMESPACE}}}}}}
|Смерти={{#invoke:Infocards|dateOfDeath|{{{3|}}}|{{{2|}}}|nocat={{{nopersoncat|}}}{{NAMESPACE}}}}
}}</includeonly><noinclude>{{doc}}</noinclude>
f8ca2c197521be2ab776e6f0791ec503e7f3206c